[#14437] Modifier Stack Refactor
patch by Ben Batt (artificer) Updated patch for 6 or so modifiers added since the patch was written. - tested with CMake and SCons - fixed one error were flags were being added to the fluids type. - remove BKE_simple_deform.h, simple_deform.c, move functions into MOD_simpledeform.c since there were problems with circular deps. - moved some fluid and boolean functions used by modifiers too.
This commit is contained in:
@@ -29,6 +29,7 @@ ADD_SUBDIRECTORY(editors)
|
|||||||
ADD_SUBDIRECTORY(avi)
|
ADD_SUBDIRECTORY(avi)
|
||||||
ADD_SUBDIRECTORY(nodes)
|
ADD_SUBDIRECTORY(nodes)
|
||||||
ADD_SUBDIRECTORY(blenkernel)
|
ADD_SUBDIRECTORY(blenkernel)
|
||||||
|
ADD_SUBDIRECTORY(modifiers)
|
||||||
ADD_SUBDIRECTORY(blenlib)
|
ADD_SUBDIRECTORY(blenlib)
|
||||||
ADD_SUBDIRECTORY(blenloader)
|
ADD_SUBDIRECTORY(blenloader)
|
||||||
ADD_SUBDIRECTORY(blenpluginapi)
|
ADD_SUBDIRECTORY(blenpluginapi)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ include nan_definitions.mk
|
|||||||
DIRS = windowmanager editors blenloader readblenfile
|
DIRS = windowmanager editors blenloader readblenfile
|
||||||
DIRS += avi imbuf render blenlib blenkernel blenpluginapi
|
DIRS += avi imbuf render blenlib blenkernel blenpluginapi
|
||||||
DIRS += makesdna makesrna
|
DIRS += makesdna makesrna
|
||||||
DIRS += python nodes gpu
|
DIRS += python nodes modifiers gpu
|
||||||
DIRS += blenfont ikplugin
|
DIRS += blenfont ikplugin
|
||||||
|
|
||||||
ifeq ($(WITH_QUICKTIME), true)
|
ifeq ($(WITH_QUICKTIME), true)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ SConscript(['avi/SConscript',
|
|||||||
'readblenfile/SConscript',
|
'readblenfile/SConscript',
|
||||||
'render/SConscript',
|
'render/SConscript',
|
||||||
'nodes/SConscript',
|
'nodes/SConscript',
|
||||||
|
'modifiers/SConscript',
|
||||||
'ikplugin/SConscript',
|
'ikplugin/SConscript',
|
||||||
'windowmanager/SConscript',
|
'windowmanager/SConscript',
|
||||||
'blenfont/SConscript'])
|
'blenfont/SConscript'])
|
||||||
|
|||||||
@@ -29,21 +29,5 @@
|
|||||||
#ifndef BKE_BOOLEANOPS_H
|
#ifndef BKE_BOOLEANOPS_H
|
||||||
#define BKE_BOOLEANOPS_H
|
#define BKE_BOOLEANOPS_H
|
||||||
|
|
||||||
struct Scene;
|
|
||||||
struct Object;
|
|
||||||
struct Base;
|
|
||||||
struct DerivedMesh;
|
|
||||||
|
|
||||||
/* Performs a boolean between two mesh objects, it is assumed that both objects
|
|
||||||
are in fact a mesh object. On success returns 1 and creates a new mesh object
|
|
||||||
into blender data structures. On failure returns 0 and reports an error. */
|
|
||||||
int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_select, int op);
|
|
||||||
|
|
||||||
|
|
||||||
/* Performs a boolean between two mesh objects, it is assumed that both objects
|
|
||||||
are in fact mesh object. On success returns a DerivedMesh. On failure
|
|
||||||
returns NULL and reports an error. */
|
|
||||||
struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select,
|
|
||||||
int int_op_type);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#ifndef BKE_FLUIDSIM_H
|
#ifndef BKE_FLUIDSIM_H
|
||||||
#define BKE_FLUIDSIM_H
|
#define BKE_FLUIDSIM_H
|
||||||
|
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
struct FluidsimModifierData;
|
struct FluidsimModifierData;
|
||||||
@@ -37,25 +38,12 @@ struct DerivedMesh;
|
|||||||
struct MVert;
|
struct MVert;
|
||||||
|
|
||||||
/* old interface */
|
/* old interface */
|
||||||
struct FluidsimSettings *fluidsimSettingsNew(struct Object *srcob);
|
|
||||||
|
|
||||||
void initElbeemMesh(struct Scene *scene, struct Object *ob,
|
void initElbeemMesh(struct Scene *scene, struct Object *ob,
|
||||||
int *numVertices, float **vertices,
|
int *numVertices, float **vertices,
|
||||||
int *numTriangles, int **triangles,
|
int *numTriangles, int **triangles,
|
||||||
int useGlobalCoords, int modifierIndex);
|
int useGlobalCoords, int modifierIndex);
|
||||||
|
|
||||||
/* new fluid-modifier interface */
|
|
||||||
void fluidsim_init(struct FluidsimModifierData *fluidmd);
|
|
||||||
void fluidsim_free(struct FluidsimModifierData *fluidmd);
|
|
||||||
|
|
||||||
struct DerivedMesh *fluidsim_read_cache(struct Object *ob, struct DerivedMesh *orgdm,
|
|
||||||
struct FluidsimModifierData *fluidmd, int framenr, int useRenderParams);
|
|
||||||
void fluidsim_read_vel_cache(struct FluidsimModifierData *fluidmd, struct DerivedMesh *dm,
|
|
||||||
char *filename);
|
|
||||||
struct DerivedMesh *fluidsimModifier_do(struct FluidsimModifierData *fluidmd,
|
|
||||||
struct Scene *scene, struct Object *ob, struct DerivedMesh *dm,
|
|
||||||
int useRenderParams, int isFinalCalc);
|
|
||||||
|
|
||||||
/* bounding box & memory estimate */
|
/* bounding box & memory estimate */
|
||||||
void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4],
|
void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4],
|
||||||
float start[3], float size[3]);
|
float start[3], float size[3]);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
FILE(GLOB SRC intern/*.c)
|
FILE(GLOB SRC intern/*.c)
|
||||||
|
|
||||||
SET(INC
|
SET(INC
|
||||||
. ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna
|
. ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna ../modifiers
|
||||||
../render/extern/include ../../../intern/decimation/extern
|
../render/extern/include ../../../intern/decimation/extern
|
||||||
../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
|
../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
|
||||||
../../../intern/iksolver/extern ../blenloader ../ikplugin
|
../../../intern/iksolver/extern ../blenloader ../ikplugin
|
||||||
@@ -38,6 +38,7 @@ SET(INC
|
|||||||
${ZLIB_INC}
|
${ZLIB_INC}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DGLEW_STATIC)
|
ADD_DEFINITIONS(-DGLEW_STATIC)
|
||||||
|
|
||||||
IF(WITH_BULLET)
|
IF(WITH_BULLET)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sources = env.Glob('intern/*.c')
|
|||||||
incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include'
|
incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include'
|
||||||
incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager'
|
incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager'
|
||||||
incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna'
|
incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna'
|
||||||
incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes'
|
incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes ../modifiers'
|
||||||
incs += ' #/intern/iksolver/extern ../blenloader'
|
incs += ' #/intern/iksolver/extern ../blenloader'
|
||||||
incs += ' #/extern/bullet2/src'
|
incs += ' #/extern/bullet2/src'
|
||||||
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
|
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
|
||||||
|
|||||||
@@ -1,595 +0,0 @@
|
|||||||
/**
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
* The Original Code is Copyright (C) Blender Foundation
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* The Original Code is: all of this file.
|
|
||||||
*
|
|
||||||
* Contributor(s): none yet.
|
|
||||||
*
|
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
|
||||||
* CSG operations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
|
||||||
|
|
||||||
#include "BLI_math.h"
|
|
||||||
#include "BLI_ghash.h"
|
|
||||||
|
|
||||||
#include "DNA_material_types.h"
|
|
||||||
#include "DNA_mesh_types.h"
|
|
||||||
#include "DNA_meshdata_types.h"
|
|
||||||
#include "DNA_object_types.h"
|
|
||||||
#include "DNA_scene_types.h"
|
|
||||||
|
|
||||||
#include "CSG_BooleanOps.h"
|
|
||||||
|
|
||||||
#include "BKE_cdderivedmesh.h"
|
|
||||||
#include "BKE_depsgraph.h"
|
|
||||||
#include "BKE_material.h"
|
|
||||||
#include "BKE_mesh.h"
|
|
||||||
#include "BKE_object.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Here's the vertex iterator structure used to walk through
|
|
||||||
* the blender vertex structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DerivedMesh *dm;
|
|
||||||
Object *ob;
|
|
||||||
int pos;
|
|
||||||
} VertexIt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementations of local vertex iterator functions.
|
|
||||||
* These describe a blender mesh to the CSG module.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void VertexIt_Destruct(CSG_VertexIteratorDescriptor * iterator)
|
|
||||||
{
|
|
||||||
if (iterator->it) {
|
|
||||||
// deallocate memory for iterator
|
|
||||||
MEM_freeN(iterator->it);
|
|
||||||
iterator->it = 0;
|
|
||||||
}
|
|
||||||
iterator->Done = NULL;
|
|
||||||
iterator->Fill = NULL;
|
|
||||||
iterator->Reset = NULL;
|
|
||||||
iterator->Step = NULL;
|
|
||||||
iterator->num_elements = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static int VertexIt_Done(CSG_IteratorPtr it)
|
|
||||||
{
|
|
||||||
VertexIt * iterator = (VertexIt *)it;
|
|
||||||
return(iterator->pos >= iterator->dm->getNumVerts(iterator->dm));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert)
|
|
||||||
{
|
|
||||||
VertexIt * iterator = (VertexIt *)it;
|
|
||||||
MVert *verts = iterator->dm->getVertArray(iterator->dm);
|
|
||||||
|
|
||||||
float global_pos[3];
|
|
||||||
|
|
||||||
/* boolean happens in global space, transform both with obmat */
|
|
||||||
mul_v3_m4v3(
|
|
||||||
global_pos,
|
|
||||||
iterator->ob->obmat,
|
|
||||||
verts[iterator->pos].co
|
|
||||||
);
|
|
||||||
|
|
||||||
vert->position[0] = global_pos[0];
|
|
||||||
vert->position[1] = global_pos[1];
|
|
||||||
vert->position[2] = global_pos[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VertexIt_Step(CSG_IteratorPtr it)
|
|
||||||
{
|
|
||||||
VertexIt * iterator = (VertexIt *)it;
|
|
||||||
iterator->pos ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VertexIt_Reset(CSG_IteratorPtr it)
|
|
||||||
{
|
|
||||||
VertexIt * iterator = (VertexIt *)it;
|
|
||||||
iterator->pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, DerivedMesh *dm, Object *ob)
|
|
||||||
{
|
|
||||||
|
|
||||||
VertexIt *it;
|
|
||||||
if (output == 0) return;
|
|
||||||
|
|
||||||
// allocate some memory for blender iterator
|
|
||||||
it = (VertexIt *)(MEM_mallocN(sizeof(VertexIt),"Boolean_VIt"));
|
|
||||||
if (it == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// assign blender specific variables
|
|
||||||
it->dm = dm;
|
|
||||||
it->ob = ob; // needed for obmat transformations
|
|
||||||
|
|
||||||
it->pos = 0;
|
|
||||||
|
|
||||||
// assign iterator function pointers.
|
|
||||||
output->Step = VertexIt_Step;
|
|
||||||
output->Fill = VertexIt_Fill;
|
|
||||||
output->Done = VertexIt_Done;
|
|
||||||
output->Reset = VertexIt_Reset;
|
|
||||||
output->num_elements = it->dm->getNumVerts(it->dm);
|
|
||||||
output->it = it;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blender Face iterator
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DerivedMesh *dm;
|
|
||||||
int pos;
|
|
||||||
int offset;
|
|
||||||
int flip;
|
|
||||||
} FaceIt;
|
|
||||||
|
|
||||||
static void FaceIt_Destruct(CSG_FaceIteratorDescriptor * iterator)
|
|
||||||
{
|
|
||||||
MEM_freeN(iterator->it);
|
|
||||||
iterator->Done = NULL;
|
|
||||||
iterator->Fill = NULL;
|
|
||||||
iterator->Reset = NULL;
|
|
||||||
iterator->Step = NULL;
|
|
||||||
iterator->num_elements = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int FaceIt_Done(CSG_IteratorPtr it)
|
|
||||||
{
|
|
||||||
// assume CSG_IteratorPtr is of the correct type.
|
|
||||||
FaceIt * iterator = (FaceIt *)it;
|
|
||||||
return(iterator->pos >= iterator->dm->getNumFaces(iterator->dm));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face)
|
|
||||||
{
|
|
||||||
// assume CSG_IteratorPtr is of the correct type.
|
|
||||||
FaceIt *face_it = (FaceIt *)it;
|
|
||||||
MFace *mfaces = face_it->dm->getFaceArray(face_it->dm);
|
|
||||||
MFace *mface = &mfaces[face_it->pos];
|
|
||||||
|
|
||||||
/* reverse face vertices if necessary */
|
|
||||||
face->vertex_index[1] = mface->v2;
|
|
||||||
if( face_it->flip == 0 ) {
|
|
||||||
face->vertex_index[0] = mface->v1;
|
|
||||||
face->vertex_index[2] = mface->v3;
|
|
||||||
} else {
|
|
||||||
face->vertex_index[2] = mface->v1;
|
|
||||||
face->vertex_index[0] = mface->v3;
|
|
||||||
}
|
|
||||||
if (mface->v4) {
|
|
||||||
face->vertex_index[3] = mface->v4;
|
|
||||||
face->vertex_number = 4;
|
|
||||||
} else {
|
|
||||||
face->vertex_number = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
face->orig_face = face_it->offset + face_it->pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FaceIt_Step(CSG_IteratorPtr it)
|
|
||||||
{
|
|
||||||
FaceIt * face_it = (FaceIt *)it;
|
|
||||||
face_it->pos ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FaceIt_Reset(CSG_IteratorPtr it)
|
|
||||||
{
|
|
||||||
FaceIt * face_it = (FaceIt *)it;
|
|
||||||
face_it->pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FaceIt_Construct(
|
|
||||||
CSG_FaceIteratorDescriptor *output, DerivedMesh *dm, int offset, Object *ob)
|
|
||||||
{
|
|
||||||
FaceIt *it;
|
|
||||||
if (output == 0) return;
|
|
||||||
|
|
||||||
// allocate some memory for blender iterator
|
|
||||||
it = (FaceIt *)(MEM_mallocN(sizeof(FaceIt),"Boolean_FIt"));
|
|
||||||
if (it == 0) {
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
// assign blender specific variables
|
|
||||||
it->dm = dm;
|
|
||||||
it->offset = offset;
|
|
||||||
it->pos = 0;
|
|
||||||
|
|
||||||
/* determine if we will need to reverse order of face vertices */
|
|
||||||
if (ob->size[0] < 0.0f) {
|
|
||||||
if (ob->size[1] < 0.0f && ob->size[2] < 0.0f) {
|
|
||||||
it->flip = 1;
|
|
||||||
} else if (ob->size[1] >= 0.0f && ob->size[2] >= 0.0f) {
|
|
||||||
it->flip = 1;
|
|
||||||
} else {
|
|
||||||
it->flip = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ob->size[1] < 0.0f && ob->size[2] < 0.0f) {
|
|
||||||
it->flip = 0;
|
|
||||||
} else if (ob->size[1] >= 0.0f && ob->size[2] >= 0.0f) {
|
|
||||||
it->flip = 0;
|
|
||||||
} else {
|
|
||||||
it->flip = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign iterator function pointers.
|
|
||||||
output->Step = FaceIt_Step;
|
|
||||||
output->Fill = FaceIt_Fill;
|
|
||||||
output->Done = FaceIt_Done;
|
|
||||||
output->Reset = FaceIt_Reset;
|
|
||||||
output->num_elements = it->dm->getNumFaces(it->dm);
|
|
||||||
output->it = it;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Object *AddNewBlenderMesh(Scene *scene, Base *base)
|
|
||||||
{
|
|
||||||
// This little function adds a new mesh object to the blender object list
|
|
||||||
// It uses ob to duplicate data as this seems to be easier than creating
|
|
||||||
// a new one. This new oject contains no faces nor vertices.
|
|
||||||
Mesh *old_me;
|
|
||||||
Base *basen;
|
|
||||||
Object *ob_new;
|
|
||||||
|
|
||||||
// now create a new blender object.
|
|
||||||
// duplicating all the settings from the previous object
|
|
||||||
// to the new one.
|
|
||||||
ob_new= copy_object(base->object);
|
|
||||||
|
|
||||||
// Ok we don't want to use the actual data from the
|
|
||||||
// last object, the above function incremented the
|
|
||||||
// number of users, so decrement it here.
|
|
||||||
old_me= ob_new->data;
|
|
||||||
old_me->id.us--;
|
|
||||||
|
|
||||||
// Now create a new base to add into the linked list of
|
|
||||||
// vase objects.
|
|
||||||
|
|
||||||
basen= MEM_mallocN(sizeof(Base), "duplibase");
|
|
||||||
*basen= *base;
|
|
||||||
BLI_addhead(&scene->base, basen); /* addhead: anders oneindige lus */
|
|
||||||
basen->object= ob_new;
|
|
||||||
basen->flag &= ~SELECT;
|
|
||||||
|
|
||||||
// Initialize the mesh data associated with this object.
|
|
||||||
ob_new->data= add_mesh("Mesh");
|
|
||||||
|
|
||||||
// Finally assign the object type.
|
|
||||||
ob_new->type= OB_MESH;
|
|
||||||
|
|
||||||
return ob_new;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InterpCSGFace(
|
|
||||||
DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr,
|
|
||||||
float mapmat[][4])
|
|
||||||
{
|
|
||||||
float obco[3], *co[4], *orig_co[4], w[4][4];
|
|
||||||
MFace *mface, *orig_mface;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
mface = CDDM_get_face(dm, index);
|
|
||||||
orig_mface = orig_dm->getFaceArray(orig_dm) + orig_index;
|
|
||||||
|
|
||||||
// get the vertex coordinates from the original mesh
|
|
||||||
orig_co[0] = (orig_dm->getVertArray(orig_dm) + orig_mface->v1)->co;
|
|
||||||
orig_co[1] = (orig_dm->getVertArray(orig_dm) + orig_mface->v2)->co;
|
|
||||||
orig_co[2] = (orig_dm->getVertArray(orig_dm) + orig_mface->v3)->co;
|
|
||||||
orig_co[3] = (orig_mface->v4)? (orig_dm->getVertArray(orig_dm) + orig_mface->v4)->co: NULL;
|
|
||||||
|
|
||||||
// get the vertex coordinates from the new derivedmesh
|
|
||||||
co[0] = CDDM_get_vert(dm, mface->v1)->co;
|
|
||||||
co[1] = CDDM_get_vert(dm, mface->v2)->co;
|
|
||||||
co[2] = CDDM_get_vert(dm, mface->v3)->co;
|
|
||||||
co[3] = (nr == 4)? CDDM_get_vert(dm, mface->v4)->co: NULL;
|
|
||||||
|
|
||||||
for (j = 0; j < nr; j++) {
|
|
||||||
// get coordinate into the space of the original mesh
|
|
||||||
if (mapmat)
|
|
||||||
mul_v3_m4v3(obco, mapmat, co[j]);
|
|
||||||
else
|
|
||||||
copy_v3_v3(obco, co[j]);
|
|
||||||
|
|
||||||
interp_weights_face_v3( w[j],orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomData_interp(&orig_dm->faceData, &dm->faceData, &orig_index, NULL, (float*)w, 1, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate over the CSG Output Descriptors and create a new DerivedMesh
|
|
||||||
from them */
|
|
||||||
static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
|
|
||||||
CSG_FaceIteratorDescriptor *face_it,
|
|
||||||
CSG_VertexIteratorDescriptor *vertex_it,
|
|
||||||
float parinv[][4],
|
|
||||||
float mapmat[][4],
|
|
||||||
Material **mat,
|
|
||||||
int *totmat,
|
|
||||||
DerivedMesh *dm1,
|
|
||||||
Object *ob1,
|
|
||||||
DerivedMesh *dm2,
|
|
||||||
Object *ob2)
|
|
||||||
{
|
|
||||||
DerivedMesh *result, *orig_dm;
|
|
||||||
GHash *material_hash = NULL;
|
|
||||||
Mesh *me1= (Mesh*)ob1->data;
|
|
||||||
Mesh *me2= (Mesh*)ob2->data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// create a new DerivedMesh
|
|
||||||
result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
|
|
||||||
CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
|
|
||||||
CD_DEFAULT, face_it->num_elements);
|
|
||||||
CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
|
|
||||||
CD_DEFAULT, face_it->num_elements);
|
|
||||||
|
|
||||||
// step through the vertex iterators:
|
|
||||||
for (i = 0; !vertex_it->Done(vertex_it->it); i++) {
|
|
||||||
CSG_IVertex csgvert;
|
|
||||||
MVert *mvert = CDDM_get_vert(result, i);
|
|
||||||
|
|
||||||
// retrieve a csg vertex from the boolean module
|
|
||||||
vertex_it->Fill(vertex_it->it, &csgvert);
|
|
||||||
vertex_it->Step(vertex_it->it);
|
|
||||||
|
|
||||||
// we have to map the vertex coordinates back in the coordinate frame
|
|
||||||
// of the resulting object, since it was computed in world space
|
|
||||||
mul_v3_m4v3(mvert->co, parinv, csgvert.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
// a hash table to remap materials to indices
|
|
||||||
if (mat) {
|
|
||||||
material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
|
||||||
*totmat = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// step through the face iterators
|
|
||||||
for(i = 0; !face_it->Done(face_it->it); i++) {
|
|
||||||
Mesh *orig_me;
|
|
||||||
Object *orig_ob;
|
|
||||||
Material *orig_mat;
|
|
||||||
CSG_IFace csgface;
|
|
||||||
MFace *mface;
|
|
||||||
int orig_index, mat_nr;
|
|
||||||
|
|
||||||
// retrieve a csg face from the boolean module
|
|
||||||
face_it->Fill(face_it->it, &csgface);
|
|
||||||
face_it->Step(face_it->it);
|
|
||||||
|
|
||||||
// find the original mesh and data
|
|
||||||
orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2;
|
|
||||||
orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2;
|
|
||||||
orig_me = (orig_ob == ob1)? me1: me2;
|
|
||||||
orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1);
|
|
||||||
|
|
||||||
// copy all face layers, including mface
|
|
||||||
CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1);
|
|
||||||
|
|
||||||
// set mface
|
|
||||||
mface = CDDM_get_face(result, i);
|
|
||||||
mface->v1 = csgface.vertex_index[0];
|
|
||||||
mface->v2 = csgface.vertex_index[1];
|
|
||||||
mface->v3 = csgface.vertex_index[2];
|
|
||||||
mface->v4 = (csgface.vertex_number == 4)? csgface.vertex_index[3]: 0;
|
|
||||||
|
|
||||||
// set material, based on lookup in hash table
|
|
||||||
orig_mat= give_current_material(orig_ob, mface->mat_nr+1);
|
|
||||||
|
|
||||||
if (mat && orig_mat) {
|
|
||||||
if (!BLI_ghash_haskey(material_hash, orig_mat)) {
|
|
||||||
mat[*totmat] = orig_mat;
|
|
||||||
mat_nr = mface->mat_nr = (*totmat)++;
|
|
||||||
BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mface->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mface->mat_nr = 0;
|
|
||||||
|
|
||||||
InterpCSGFace(result, orig_dm, i, orig_index, csgface.vertex_number,
|
|
||||||
(orig_me == me2)? mapmat: NULL);
|
|
||||||
|
|
||||||
test_index_face(mface, &result->faceData, i, csgface.vertex_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (material_hash)
|
|
||||||
BLI_ghash_free(material_hash, NULL, NULL);
|
|
||||||
|
|
||||||
CDDM_calc_edges(result);
|
|
||||||
CDDM_calc_normals(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BuildMeshDescriptors(
|
|
||||||
struct DerivedMesh *dm,
|
|
||||||
struct Object *ob,
|
|
||||||
int face_offset,
|
|
||||||
struct CSG_FaceIteratorDescriptor * face_it,
|
|
||||||
struct CSG_VertexIteratorDescriptor * vertex_it)
|
|
||||||
{
|
|
||||||
VertexIt_Construct(vertex_it,dm, ob);
|
|
||||||
FaceIt_Construct(face_it,dm,face_offset,ob);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FreeMeshDescriptors(
|
|
||||||
struct CSG_FaceIteratorDescriptor *face_it,
|
|
||||||
struct CSG_VertexIteratorDescriptor *vertex_it)
|
|
||||||
{
|
|
||||||
VertexIt_Destruct(vertex_it);
|
|
||||||
FaceIt_Destruct(face_it);
|
|
||||||
}
|
|
||||||
|
|
||||||
DerivedMesh *NewBooleanDerivedMesh_intern(
|
|
||||||
DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select,
|
|
||||||
int int_op_type, Material **mat, int *totmat)
|
|
||||||
{
|
|
||||||
|
|
||||||
float inv_mat[4][4];
|
|
||||||
float map_mat[4][4];
|
|
||||||
|
|
||||||
DerivedMesh *result = NULL;
|
|
||||||
|
|
||||||
if (dm == NULL || dm_select == NULL) return 0;
|
|
||||||
if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) return 0;
|
|
||||||
|
|
||||||
// we map the final object back into ob's local coordinate space. For this
|
|
||||||
// we need to compute the inverse transform from global to ob (inv_mat),
|
|
||||||
// and the transform from ob to ob_select for use in interpolation (map_mat)
|
|
||||||
invert_m4_m4(inv_mat, ob->obmat);
|
|
||||||
mul_m4_m4m4(map_mat, ob_select->obmat, inv_mat);
|
|
||||||
invert_m4_m4(inv_mat, ob_select->obmat);
|
|
||||||
|
|
||||||
{
|
|
||||||
// interface with the boolean module:
|
|
||||||
//
|
|
||||||
// the idea is, we pass the boolean module verts and faces using the
|
|
||||||
// provided descriptors. once the boolean operation is performed, we
|
|
||||||
// get back output descriptors, from which we then build a DerivedMesh
|
|
||||||
|
|
||||||
CSG_VertexIteratorDescriptor vd_1, vd_2;
|
|
||||||
CSG_FaceIteratorDescriptor fd_1, fd_2;
|
|
||||||
CSG_OperationType op_type;
|
|
||||||
CSG_BooleanOperation *bool_op;
|
|
||||||
|
|
||||||
// work out the operation they chose and pick the appropriate
|
|
||||||
// enum from the csg module.
|
|
||||||
switch (int_op_type) {
|
|
||||||
case 1 : op_type = e_csg_intersection; break;
|
|
||||||
case 2 : op_type = e_csg_union; break;
|
|
||||||
case 3 : op_type = e_csg_difference; break;
|
|
||||||
case 4 : op_type = e_csg_classify; break;
|
|
||||||
default : op_type = e_csg_intersection;
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildMeshDescriptors(dm_select, ob_select, 0, &fd_1, &vd_1);
|
|
||||||
BuildMeshDescriptors(dm, ob, dm_select->getNumFaces(dm_select) , &fd_2, &vd_2);
|
|
||||||
|
|
||||||
bool_op = CSG_NewBooleanFunction();
|
|
||||||
|
|
||||||
// perform the operation
|
|
||||||
if (CSG_PerformBooleanOperation(bool_op, op_type, fd_1, vd_1, fd_2, vd_2)) {
|
|
||||||
CSG_VertexIteratorDescriptor vd_o;
|
|
||||||
CSG_FaceIteratorDescriptor fd_o;
|
|
||||||
|
|
||||||
CSG_OutputFaceDescriptor(bool_op, &fd_o);
|
|
||||||
CSG_OutputVertexDescriptor(bool_op, &vd_o);
|
|
||||||
|
|
||||||
// iterate through results of operation and insert
|
|
||||||
// into new object
|
|
||||||
result = ConvertCSGDescriptorsToDerivedMesh(
|
|
||||||
&fd_o, &vd_o, inv_mat, map_mat, mat, totmat, dm_select, ob_select, dm, ob);
|
|
||||||
|
|
||||||
// free up the memory
|
|
||||||
CSG_FreeVertexDescriptor(&vd_o);
|
|
||||||
CSG_FreeFaceDescriptor(&fd_o);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("Unknown internal error in boolean");
|
|
||||||
|
|
||||||
CSG_FreeBooleanOperation(bool_op);
|
|
||||||
|
|
||||||
FreeMeshDescriptors(&fd_1, &vd_1);
|
|
||||||
FreeMeshDescriptors(&fd_2, &vd_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
|
|
||||||
{
|
|
||||||
Mesh *me_new;
|
|
||||||
int a, maxmat, totmat= 0;
|
|
||||||
Object *ob_new, *ob, *ob_select;
|
|
||||||
Material **mat;
|
|
||||||
DerivedMesh *result;
|
|
||||||
DerivedMesh *dm_select;
|
|
||||||
DerivedMesh *dm;
|
|
||||||
|
|
||||||
ob= base->object;
|
|
||||||
ob_select= base_select->object;
|
|
||||||
|
|
||||||
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
|
||||||
dm_select = mesh_create_derived_view(scene, ob_select, 0); // no modifiers in editmode ??
|
|
||||||
|
|
||||||
maxmat= ob->totcol + ob_select->totcol;
|
|
||||||
mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat");
|
|
||||||
|
|
||||||
/* put some checks in for nice user feedback */
|
|
||||||
if (dm == NULL || dm_select == NULL) return 0;
|
|
||||||
if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select))
|
|
||||||
{
|
|
||||||
MEM_freeN(mat);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
result= NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, mat, &totmat);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
MEM_freeN(mat);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a new blender mesh object - using 'base' as a template */
|
|
||||||
ob_new= AddNewBlenderMesh(scene, base_select);
|
|
||||||
me_new= ob_new->data;
|
|
||||||
|
|
||||||
DM_to_mesh(result, me_new);
|
|
||||||
result->release(result);
|
|
||||||
|
|
||||||
dm->release(dm);
|
|
||||||
dm_select->release(dm_select);
|
|
||||||
|
|
||||||
/* add materials to object */
|
|
||||||
for (a = 0; a < totmat; a++)
|
|
||||||
assign_material(ob_new, mat[a], a+1);
|
|
||||||
|
|
||||||
MEM_freeN(mat);
|
|
||||||
|
|
||||||
/* update dag */
|
|
||||||
DAG_id_flush_update(&ob_new->id, OB_RECALC_DATA);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select,
|
|
||||||
int int_op_type)
|
|
||||||
{
|
|
||||||
return NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,547 +62,6 @@
|
|||||||
|
|
||||||
/* ************************* fluidsim bobj file handling **************************** */
|
/* ************************* fluidsim bobj file handling **************************** */
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
// forward decleration
|
|
||||||
// -----------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
|
|
||||||
void fluidsim_init(FluidsimModifierData *fluidmd)
|
|
||||||
{
|
|
||||||
#ifndef DISABLE_ELBEEM
|
|
||||||
if(fluidmd)
|
|
||||||
{
|
|
||||||
FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings");
|
|
||||||
|
|
||||||
fluidmd->fss = fss;
|
|
||||||
|
|
||||||
if(!fss)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fss->fmd = fluidmd;
|
|
||||||
fss->type = OB_FLUIDSIM_ENABLE;
|
|
||||||
fss->show_advancedoptions = 0;
|
|
||||||
|
|
||||||
fss->resolutionxyz = 65;
|
|
||||||
fss->previewresxyz = 45;
|
|
||||||
fss->realsize = 0.5;
|
|
||||||
fss->guiDisplayMode = 2; // preview
|
|
||||||
fss->renderDisplayMode = 3; // render
|
|
||||||
|
|
||||||
fss->viscosityMode = 2; // default to water
|
|
||||||
fss->viscosityValue = 1.0;
|
|
||||||
fss->viscosityExponent = 6;
|
|
||||||
|
|
||||||
// dg TODO: change this to []
|
|
||||||
fss->gravx = 0.0;
|
|
||||||
fss->gravy = 0.0;
|
|
||||||
fss->gravz = -9.81;
|
|
||||||
fss->animStart = 0.0;
|
|
||||||
fss->animEnd = 4.0;
|
|
||||||
fss->gstar = 0.005; // used as normgstar
|
|
||||||
fss->maxRefine = -1;
|
|
||||||
// maxRefine is set according to resolutionxyz during bake
|
|
||||||
|
|
||||||
// fluid/inflow settings
|
|
||||||
// fss->iniVel --> automatically set to 0
|
|
||||||
|
|
||||||
/* elubie: changed this to default to the same dir as the render output
|
|
||||||
to prevent saving to C:\ on Windows */
|
|
||||||
BLI_strncpy(fss->surfdataPath, btempdir, FILE_MAX);
|
|
||||||
|
|
||||||
// first init of bounding box
|
|
||||||
// no bounding box needed
|
|
||||||
|
|
||||||
// todo - reuse default init from elbeem!
|
|
||||||
fss->typeFlags = OB_FSBND_PARTSLIP;
|
|
||||||
fss->domainNovecgen = 0;
|
|
||||||
fss->volumeInitType = 1; // volume
|
|
||||||
fss->partSlipValue = 0.2;
|
|
||||||
|
|
||||||
fss->generateTracers = 0;
|
|
||||||
fss->generateParticles = 0.0;
|
|
||||||
fss->surfaceSmoothing = 1.0;
|
|
||||||
fss->surfaceSubdivs = 0.0;
|
|
||||||
fss->particleInfSize = 0.0;
|
|
||||||
fss->particleInfAlpha = 0.0;
|
|
||||||
|
|
||||||
// init fluid control settings
|
|
||||||
fss->attractforceStrength = 0.2;
|
|
||||||
fss->attractforceRadius = 0.75;
|
|
||||||
fss->velocityforceStrength = 0.2;
|
|
||||||
fss->velocityforceRadius = 0.75;
|
|
||||||
fss->cpsTimeStart = fss->animStart;
|
|
||||||
fss->cpsTimeEnd = fss->animEnd;
|
|
||||||
fss->cpsQuality = 10.0; // 1.0 / 10.0 => means 0.1 width
|
|
||||||
|
|
||||||
/*
|
|
||||||
BAD TODO: this is done in buttons_object.c in the moment
|
|
||||||
Mesh *mesh = ob->data;
|
|
||||||
// calculate bounding box
|
|
||||||
fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// (ab)used to store velocities
|
|
||||||
fss->meshSurfNormals = NULL;
|
|
||||||
|
|
||||||
fss->lastgoodframe = -1;
|
|
||||||
|
|
||||||
fss->flag |= OB_FLUIDSIM_ACTIVE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fluidsim_free(FluidsimModifierData *fluidmd)
|
|
||||||
{
|
|
||||||
#ifndef DISABLE_ELBEEM
|
|
||||||
if(fluidmd)
|
|
||||||
{
|
|
||||||
if(fluidmd->fss->meshSurfNormals)
|
|
||||||
{
|
|
||||||
MEM_freeN(fluidmd->fss->meshSurfNormals);
|
|
||||||
fluidmd->fss->meshSurfNormals = NULL;
|
|
||||||
}
|
|
||||||
MEM_freeN(fluidmd->fss);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
|
|
||||||
{
|
|
||||||
#ifndef DISABLE_ELBEEM
|
|
||||||
DerivedMesh *result = NULL;
|
|
||||||
int framenr;
|
|
||||||
FluidsimSettings *fss = NULL;
|
|
||||||
|
|
||||||
framenr= (int)scene->r.cfra;
|
|
||||||
|
|
||||||
// only handle fluidsim domains
|
|
||||||
if(fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN))
|
|
||||||
return dm;
|
|
||||||
|
|
||||||
// sanity check
|
|
||||||
if(!fluidmd || (fluidmd && !fluidmd->fss))
|
|
||||||
return dm;
|
|
||||||
|
|
||||||
fss = fluidmd->fss;
|
|
||||||
|
|
||||||
// timescale not supported yet
|
|
||||||
// clmd->sim_parms->timescale= timescale;
|
|
||||||
|
|
||||||
// support reversing of baked fluid frames here
|
|
||||||
if((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0))
|
|
||||||
{
|
|
||||||
framenr = fss->lastgoodframe - framenr + 1;
|
|
||||||
CLAMP(framenr, 1, fss->lastgoodframe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to read from cache */
|
|
||||||
if(((fss->lastgoodframe >= framenr) || (fss->lastgoodframe < 0)) && (result = fluidsim_read_cache(ob, dm, fluidmd, framenr, useRenderParams)))
|
|
||||||
{
|
|
||||||
// fss->lastgoodframe = framenr; // set also in src/fluidsim.c
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// display last known good frame
|
|
||||||
if(fss->lastgoodframe >= 0)
|
|
||||||
{
|
|
||||||
if((result = fluidsim_read_cache(ob, dm, fluidmd, fss->lastgoodframe, useRenderParams)))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// it was supposed to be a valid frame but it isn't!
|
|
||||||
fss->lastgoodframe = framenr - 1;
|
|
||||||
|
|
||||||
|
|
||||||
// this could be likely the case when you load an old fluidsim
|
|
||||||
if((result = fluidsim_read_cache(ob, dm, fluidmd, fss->lastgoodframe, useRenderParams)))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = CDDM_copy(dm);
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dm;
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_ELBEEM
|
|
||||||
/* read .bobj.gz file into a fluidsimDerivedMesh struct */
|
|
||||||
static DerivedMesh *fluidsim_read_obj(char *filename)
|
|
||||||
{
|
|
||||||
int wri,i,j;
|
|
||||||
float wrf;
|
|
||||||
int gotBytes;
|
|
||||||
gzFile gzf;
|
|
||||||
int numverts = 0, numfaces = 0;
|
|
||||||
DerivedMesh *dm = NULL;
|
|
||||||
MFace *mface;
|
|
||||||
MVert *mvert;
|
|
||||||
short *normals;
|
|
||||||
|
|
||||||
// ------------------------------------------------
|
|
||||||
// get numverts + numfaces first
|
|
||||||
// ------------------------------------------------
|
|
||||||
gzf = gzopen(filename, "rb");
|
|
||||||
if (!gzf)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read numverts
|
|
||||||
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
|
||||||
numverts = wri;
|
|
||||||
|
|
||||||
// skip verts
|
|
||||||
for(i=0; i<numverts*3; i++)
|
|
||||||
{
|
|
||||||
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
|
||||||
}
|
|
||||||
|
|
||||||
// read number of normals
|
|
||||||
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
|
||||||
|
|
||||||
// skip normals
|
|
||||||
for(i=0; i<numverts*3; i++)
|
|
||||||
{
|
|
||||||
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get no. of triangles */
|
|
||||||
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
|
||||||
numfaces = wri;
|
|
||||||
|
|
||||||
gzclose( gzf );
|
|
||||||
// ------------------------------------------------
|
|
||||||
|
|
||||||
if(!numfaces || !numverts)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
gzf = gzopen(filename, "rb");
|
|
||||||
if (!gzf)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm = CDDM_new(numverts, 0, numfaces);
|
|
||||||
|
|
||||||
if(!dm)
|
|
||||||
{
|
|
||||||
gzclose( gzf );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read numverts
|
|
||||||
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
|
||||||
|
|
||||||
// read vertex position from file
|
|
||||||
mvert = CDDM_get_verts(dm);
|
|
||||||
for(i=0; i<numverts; i++)
|
|
||||||
{
|
|
||||||
MVert *mv = &mvert[i];
|
|
||||||
|
|
||||||
for(j=0; j<3; j++)
|
|
||||||
{
|
|
||||||
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
|
||||||
mv->co[j] = wrf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// should be the same as numverts
|
|
||||||
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
|
||||||
if(wri != numverts)
|
|
||||||
{
|
|
||||||
if(dm)
|
|
||||||
dm->release(dm);
|
|
||||||
gzclose( gzf );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
normals = MEM_callocN(sizeof(short) * numverts * 3, "fluid_tmp_normals" );
|
|
||||||
if(!normals)
|
|
||||||
{
|
|
||||||
if(dm)
|
|
||||||
dm->release(dm);
|
|
||||||
gzclose( gzf );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read normals from file (but don't save them yet)
|
|
||||||
for(i=0; i<numverts*3; i++)
|
|
||||||
{
|
|
||||||
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
|
||||||
normals[i] = (short)(wrf*32767.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read no. of triangles */
|
|
||||||
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
|
||||||
|
|
||||||
if(wri!=numfaces)
|
|
||||||
printf("Fluidsim: error in reading data from file.\n");
|
|
||||||
|
|
||||||
// read triangles from file
|
|
||||||
mface = CDDM_get_faces(dm);
|
|
||||||
for(i=0; i<numfaces; i++)
|
|
||||||
{
|
|
||||||
int face[4];
|
|
||||||
MFace *mf = &mface[i];
|
|
||||||
|
|
||||||
gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] ));
|
|
||||||
gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] ));
|
|
||||||
gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] ));
|
|
||||||
face[3] = 0;
|
|
||||||
|
|
||||||
// check if 3rd vertex has index 0 (not allowed in blender)
|
|
||||||
if(face[2])
|
|
||||||
{
|
|
||||||
mf->v1 = face[0];
|
|
||||||
mf->v2 = face[1];
|
|
||||||
mf->v3 = face[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mf->v1 = face[1];
|
|
||||||
mf->v2 = face[2];
|
|
||||||
mf->v3 = face[0];
|
|
||||||
}
|
|
||||||
mf->v4 = face[3];
|
|
||||||
|
|
||||||
test_index_face(mf, NULL, 0, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
gzclose( gzf );
|
|
||||||
|
|
||||||
CDDM_calc_edges(dm);
|
|
||||||
|
|
||||||
CDDM_apply_vert_normals(dm, (short (*)[3])normals);
|
|
||||||
MEM_freeN(normals);
|
|
||||||
|
|
||||||
// CDDM_calc_normals(result);
|
|
||||||
|
|
||||||
return dm;
|
|
||||||
}
|
|
||||||
|
|
||||||
DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
|
|
||||||
{
|
|
||||||
int displaymode = 0;
|
|
||||||
int curFrame = framenr - 1 /*scene->r.sfra*/; /* start with 0 at start frame */
|
|
||||||
char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR];
|
|
||||||
FluidsimSettings *fss = fluidmd->fss;
|
|
||||||
DerivedMesh *dm = NULL;
|
|
||||||
MFace *mface;
|
|
||||||
int numfaces;
|
|
||||||
int mat_nr, flag, i;
|
|
||||||
|
|
||||||
if(!useRenderParams) {
|
|
||||||
displaymode = fss->guiDisplayMode;
|
|
||||||
} else {
|
|
||||||
displaymode = fss->renderDisplayMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(targetDir, fss->surfdataPath, FILE_MAXDIR);
|
|
||||||
|
|
||||||
// use preview or final mesh?
|
|
||||||
if(displaymode==1)
|
|
||||||
{
|
|
||||||
// just display original object
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if(displaymode==2)
|
|
||||||
{
|
|
||||||
strcat(targetDir,"fluidsurface_preview_####");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // 3
|
|
||||||
strcat(targetDir,"fluidsurface_final_####");
|
|
||||||
}
|
|
||||||
|
|
||||||
BLI_path_abs(targetDir, G.sce);
|
|
||||||
BLI_path_frame(targetDir, curFrame, 0); // fixed #frame-no
|
|
||||||
|
|
||||||
strcpy(targetFile,targetDir);
|
|
||||||
strcat(targetFile, ".bobj.gz");
|
|
||||||
|
|
||||||
dm = fluidsim_read_obj(targetFile);
|
|
||||||
|
|
||||||
if(!dm)
|
|
||||||
{
|
|
||||||
// switch, abort background rendering when fluidsim mesh is missing
|
|
||||||
const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp
|
|
||||||
|
|
||||||
if(G.background==1) {
|
|
||||||
if(getenv(strEnvName2)) {
|
|
||||||
int elevel = atoi(getenv(strEnvName2));
|
|
||||||
if(elevel>0) {
|
|
||||||
printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",strEnvName2, targetFile);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// display org. object upon failure which is in dm
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign material + flags to new dm
|
|
||||||
mface = orgdm->getFaceArray(orgdm);
|
|
||||||
mat_nr = mface[0].mat_nr;
|
|
||||||
flag = mface[0].flag;
|
|
||||||
|
|
||||||
mface = dm->getFaceArray(dm);
|
|
||||||
numfaces = dm->getNumFaces(dm);
|
|
||||||
for(i=0; i<numfaces; i++)
|
|
||||||
{
|
|
||||||
mface[i].mat_nr = mat_nr;
|
|
||||||
mface[i].flag = flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load vertex velocities, if they exist...
|
|
||||||
// TODO? use generate flag as loading flag as well?
|
|
||||||
// warning, needs original .bobj.gz mesh loading filename
|
|
||||||
if(displaymode==3)
|
|
||||||
{
|
|
||||||
fluidsim_read_vel_cache(fluidmd, dm, targetFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(fss->meshSurfNormals)
|
|
||||||
MEM_freeN(fss->meshSurfNormals);
|
|
||||||
|
|
||||||
fss->meshSurfNormals = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
|
|
||||||
void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename)
|
|
||||||
{
|
|
||||||
int wri, i, j;
|
|
||||||
float wrf;
|
|
||||||
gzFile gzf;
|
|
||||||
FluidsimSettings *fss = fluidmd->fss;
|
|
||||||
int len = strlen(filename);
|
|
||||||
int totvert = dm->getNumVerts(dm);
|
|
||||||
float *velarray = NULL;
|
|
||||||
|
|
||||||
// mesh and vverts have to be valid from loading...
|
|
||||||
|
|
||||||
if(fss->meshSurfNormals)
|
|
||||||
MEM_freeN(fss->meshSurfNormals);
|
|
||||||
|
|
||||||
if(len<7)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fss->domainNovecgen>0) return;
|
|
||||||
|
|
||||||
// abusing pointer to hold an array of 3d-velocities
|
|
||||||
fss->meshSurfNormals = MEM_callocN(sizeof(float)*3*dm->getNumVerts(dm), "Fluidsim_velocities");
|
|
||||||
// abusing pointer to hold an INT
|
|
||||||
fss->meshSurface = SET_INT_IN_POINTER(totvert);
|
|
||||||
|
|
||||||
velarray = (float *)fss->meshSurfNormals;
|
|
||||||
|
|
||||||
// .bobj.gz , correct filename
|
|
||||||
// 87654321
|
|
||||||
filename[len-6] = 'v';
|
|
||||||
filename[len-5] = 'e';
|
|
||||||
filename[len-4] = 'l';
|
|
||||||
|
|
||||||
gzf = gzopen(filename, "rb");
|
|
||||||
if (!gzf)
|
|
||||||
{
|
|
||||||
MEM_freeN(fss->meshSurfNormals);
|
|
||||||
fss->meshSurfNormals = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gzread(gzf, &wri, sizeof( wri ));
|
|
||||||
if(wri != totvert)
|
|
||||||
{
|
|
||||||
MEM_freeN(fss->meshSurfNormals);
|
|
||||||
fss->meshSurfNormals = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<totvert;i++)
|
|
||||||
{
|
|
||||||
for(j=0; j<3; j++)
|
|
||||||
{
|
|
||||||
gzread(gzf, &wrf, sizeof( wrf ));
|
|
||||||
velarray[3*i + j] = wrf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gzclose(gzf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
|
|
||||||
/*RET*/ float start[3], /*RET*/ float size[3] )
|
|
||||||
{
|
|
||||||
float bbsx=0.0, bbsy=0.0, bbsz=0.0;
|
|
||||||
float bbex=1.0, bbey=1.0, bbez=1.0;
|
|
||||||
int i;
|
|
||||||
float vec[3];
|
|
||||||
|
|
||||||
if(totvert == 0) {
|
|
||||||
zero_v3(start);
|
|
||||||
zero_v3(size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VECCOPY(vec, mvert[0].co);
|
|
||||||
mul_m4_v3(obmat, vec);
|
|
||||||
bbsx = vec[0]; bbsy = vec[1]; bbsz = vec[2];
|
|
||||||
bbex = vec[0]; bbey = vec[1]; bbez = vec[2];
|
|
||||||
|
|
||||||
for(i = 1; i < totvert; i++) {
|
|
||||||
VECCOPY(vec, mvert[i].co);
|
|
||||||
mul_m4_v3(obmat, vec);
|
|
||||||
|
|
||||||
if(vec[0] < bbsx){ bbsx= vec[0]; }
|
|
||||||
if(vec[1] < bbsy){ bbsy= vec[1]; }
|
|
||||||
if(vec[2] < bbsz){ bbsz= vec[2]; }
|
|
||||||
if(vec[0] > bbex){ bbex= vec[0]; }
|
|
||||||
if(vec[1] > bbey){ bbey= vec[1]; }
|
|
||||||
if(vec[2] > bbez){ bbez= vec[2]; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// return values...
|
|
||||||
if(start) {
|
|
||||||
start[0] = bbsx;
|
|
||||||
start[1] = bbsy;
|
|
||||||
start[2] = bbsz;
|
|
||||||
}
|
|
||||||
if(size) {
|
|
||||||
size[0] = bbex-bbsx;
|
|
||||||
size[1] = bbey-bbsy;
|
|
||||||
size[2] = bbez-bbsz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
// old interface
|
|
||||||
//-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
// file handling
|
// file handling
|
||||||
@@ -665,21 +124,3 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
|
|||||||
|
|
||||||
dm->release(dm);
|
dm->release(dm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fluid_estimate_memory(Object *ob, FluidsimSettings *fss, char *value)
|
|
||||||
{
|
|
||||||
Mesh *mesh;
|
|
||||||
|
|
||||||
value[0]= '\0';
|
|
||||||
|
|
||||||
if(ob->type == OB_MESH) {
|
|
||||||
/* use mesh bounding box and object scaling */
|
|
||||||
mesh= ob->data;
|
|
||||||
|
|
||||||
fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
|
|
||||||
elbeemEstimateMemreq(fss->resolutionxyz, fss->bbSize[0],fss->bbSize[1],fss->bbSize[2], fss->maxRefine, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DISABLE_ELBEEM
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,255 +0,0 @@
|
|||||||
/**
|
|
||||||
* deform_simple.c
|
|
||||||
*
|
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
* The Original Code is Copyright (C) Blender Foundation.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* The Original Code is: all of this file.
|
|
||||||
*
|
|
||||||
* Contributor(s): André Pinto
|
|
||||||
*
|
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
|
||||||
*/
|
|
||||||
#include "DNA_object_types.h"
|
|
||||||
#include "DNA_modifier_types.h"
|
|
||||||
#include "DNA_meshdata_types.h"
|
|
||||||
|
|
||||||
#include "BKE_DerivedMesh.h"
|
|
||||||
#include "BKE_lattice.h"
|
|
||||||
#include "BKE_deform.h"
|
|
||||||
#include "BKE_utildefines.h"
|
|
||||||
#include "BLI_math.h"
|
|
||||||
#include "BKE_shrinkwrap.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
|
|
||||||
//Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1]
|
|
||||||
//The ammount of clamp is saved on dcut
|
|
||||||
static void axis_limit(int axis, const float limits[2], float co[3], float dcut[3])
|
|
||||||
{
|
|
||||||
float val = co[axis];
|
|
||||||
if(limits[0] > val) val = limits[0];
|
|
||||||
if(limits[1] < val) val = limits[1];
|
|
||||||
|
|
||||||
dcut[axis] = co[axis] - val;
|
|
||||||
co[axis] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simpleDeform_taper(const float factor, const float dcut[3], float *co)
|
|
||||||
{
|
|
||||||
float x = co[0], y = co[1], z = co[2];
|
|
||||||
float scale = z*factor;
|
|
||||||
|
|
||||||
co[0] = x + x*scale;
|
|
||||||
co[1] = y + y*scale;
|
|
||||||
co[2] = z;
|
|
||||||
|
|
||||||
if(dcut)
|
|
||||||
{
|
|
||||||
co[0] += dcut[0];
|
|
||||||
co[1] += dcut[1];
|
|
||||||
co[2] += dcut[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simpleDeform_stretch(const float factor, const float dcut[3], float *co)
|
|
||||||
{
|
|
||||||
float x = co[0], y = co[1], z = co[2];
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
scale = (z*z*factor-factor + 1.0);
|
|
||||||
|
|
||||||
co[0] = x*scale;
|
|
||||||
co[1] = y*scale;
|
|
||||||
co[2] = z*(1.0+factor);
|
|
||||||
|
|
||||||
|
|
||||||
if(dcut)
|
|
||||||
{
|
|
||||||
co[0] += dcut[0];
|
|
||||||
co[1] += dcut[1];
|
|
||||||
co[2] += dcut[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simpleDeform_twist(const float factor, const float *dcut, float *co)
|
|
||||||
{
|
|
||||||
float x = co[0], y = co[1], z = co[2];
|
|
||||||
float theta, sint, cost;
|
|
||||||
|
|
||||||
theta = z*factor;
|
|
||||||
sint = sin(theta);
|
|
||||||
cost = cos(theta);
|
|
||||||
|
|
||||||
co[0] = x*cost - y*sint;
|
|
||||||
co[1] = x*sint + y*cost;
|
|
||||||
co[2] = z;
|
|
||||||
|
|
||||||
if(dcut)
|
|
||||||
{
|
|
||||||
co[0] += dcut[0];
|
|
||||||
co[1] += dcut[1];
|
|
||||||
co[2] += dcut[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simpleDeform_bend(const float factor, const float dcut[3], float *co)
|
|
||||||
{
|
|
||||||
float x = co[0], y = co[1], z = co[2];
|
|
||||||
float theta, sint, cost;
|
|
||||||
|
|
||||||
theta = x*factor;
|
|
||||||
sint = sin(theta);
|
|
||||||
cost = cos(theta);
|
|
||||||
|
|
||||||
if(fabs(factor) > 1e-7f)
|
|
||||||
{
|
|
||||||
co[0] = -(y-1.0f/factor)*sint;
|
|
||||||
co[1] = (y-1.0f/factor)*cost + 1.0f/factor;
|
|
||||||
co[2] = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(dcut)
|
|
||||||
{
|
|
||||||
co[0] += cost*dcut[0];
|
|
||||||
co[1] += sint*dcut[0];
|
|
||||||
co[2] += dcut[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* simple deform modifier */
|
|
||||||
void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
|
|
||||||
{
|
|
||||||
static const float lock_axis[2] = {0.0f, 0.0f};
|
|
||||||
|
|
||||||
int i;
|
|
||||||
int limit_axis = 0;
|
|
||||||
float smd_limit[2], smd_factor;
|
|
||||||
SpaceTransform *transf = NULL, tmp_transf;
|
|
||||||
void (*simpleDeform_callback)(const float factor, const float dcut[3], float *co) = NULL; //Mode callback
|
|
||||||
int vgroup = defgroup_name_index(ob, smd->vgroup_name);
|
|
||||||
MDeformVert *dvert = NULL;
|
|
||||||
|
|
||||||
//Safe-check
|
|
||||||
if(smd->origin == ob) smd->origin = NULL; //No self references
|
|
||||||
|
|
||||||
if(smd->limit[0] < 0.0) smd->limit[0] = 0.0f;
|
|
||||||
if(smd->limit[0] > 1.0) smd->limit[0] = 1.0f;
|
|
||||||
|
|
||||||
smd->limit[0] = MIN2(smd->limit[0], smd->limit[1]); //Upper limit >= than lower limit
|
|
||||||
|
|
||||||
//Calculate matrixs do convert between coordinate spaces
|
|
||||||
if(smd->origin)
|
|
||||||
{
|
|
||||||
transf = &tmp_transf;
|
|
||||||
|
|
||||||
if(smd->originOpts & MOD_SIMPLEDEFORM_ORIGIN_LOCAL)
|
|
||||||
{
|
|
||||||
space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
copy_m4_m4(transf->local2target, smd->origin->obmat);
|
|
||||||
invert_m4_m4(transf->target2local, transf->local2target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Setup vars
|
|
||||||
limit_axis = (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) ? 0 : 2; //Bend limits on X.. all other modes limit on Z
|
|
||||||
|
|
||||||
//Update limits if needed
|
|
||||||
{
|
|
||||||
float lower = FLT_MAX;
|
|
||||||
float upper = -FLT_MAX;
|
|
||||||
|
|
||||||
for(i=0; i<numVerts; i++)
|
|
||||||
{
|
|
||||||
float tmp[3];
|
|
||||||
VECCOPY(tmp, vertexCos[i]);
|
|
||||||
|
|
||||||
if(transf) space_transform_apply(transf, tmp);
|
|
||||||
|
|
||||||
lower = MIN2(lower, tmp[limit_axis]);
|
|
||||||
upper = MAX2(upper, tmp[limit_axis]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//SMD values are normalized to the BV, calculate the absolut values
|
|
||||||
smd_limit[1] = lower + (upper-lower)*smd->limit[1];
|
|
||||||
smd_limit[0] = lower + (upper-lower)*smd->limit[0];
|
|
||||||
|
|
||||||
smd_factor = smd->factor / MAX2(FLT_EPSILON, smd_limit[1]-smd_limit[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(dm)
|
|
||||||
{
|
|
||||||
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
|
||||||
}
|
|
||||||
else if(ob->type == OB_LATTICE)
|
|
||||||
{
|
|
||||||
dvert = lattice_get_deform_verts(ob);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch(smd->mode)
|
|
||||||
{
|
|
||||||
case MOD_SIMPLEDEFORM_MODE_TWIST: simpleDeform_callback = simpleDeform_twist; break;
|
|
||||||
case MOD_SIMPLEDEFORM_MODE_BEND: simpleDeform_callback = simpleDeform_bend; break;
|
|
||||||
case MOD_SIMPLEDEFORM_MODE_TAPER: simpleDeform_callback = simpleDeform_taper; break;
|
|
||||||
case MOD_SIMPLEDEFORM_MODE_STRETCH: simpleDeform_callback = simpleDeform_stretch; break;
|
|
||||||
default:
|
|
||||||
return; //No simpledeform mode?
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<numVerts; i++)
|
|
||||||
{
|
|
||||||
float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
|
|
||||||
|
|
||||||
if(weight != 0.0f)
|
|
||||||
{
|
|
||||||
float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
|
|
||||||
|
|
||||||
if(transf) space_transform_apply(transf, vertexCos[i]);
|
|
||||||
|
|
||||||
VECCOPY(co, vertexCos[i]);
|
|
||||||
|
|
||||||
//Apply axis limits
|
|
||||||
if(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) //Bend mode shoulnt have any lock axis
|
|
||||||
{
|
|
||||||
if(smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) axis_limit(0, lock_axis, co, dcut);
|
|
||||||
if(smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) axis_limit(1, lock_axis, co, dcut);
|
|
||||||
}
|
|
||||||
axis_limit(limit_axis, smd_limit, co, dcut);
|
|
||||||
|
|
||||||
simpleDeform_callback(smd_factor, dcut, co); //Apply deform
|
|
||||||
interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); //Use vertex weight has coef of linear interpolation
|
|
||||||
|
|
||||||
if(transf) space_transform_invert(transf, vertexCos[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
63
source/blender/modifiers/CMakeLists.txt
Normal file
63
source/blender/modifiers/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The Original Code is: all of this file.
|
||||||
|
#
|
||||||
|
# Contributor(s): Jacques Beaurain
|
||||||
|
# Ben Batt
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
|
||||||
|
FILE(GLOB SRC intern/*.c)
|
||||||
|
|
||||||
|
SET(INC
|
||||||
|
. ./intern
|
||||||
|
../../../intern/guardedalloc
|
||||||
|
../include
|
||||||
|
../blenlib
|
||||||
|
../makesdna
|
||||||
|
../blenkernel
|
||||||
|
../blenkernel/intern
|
||||||
|
../render/extern/include
|
||||||
|
../../../intern/decimation/extern
|
||||||
|
../../../intern/elbeem/extern
|
||||||
|
../../../intern/bsp/extern
|
||||||
|
${ZLIB_INC}
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(WITH_LZO)
|
||||||
|
SET(INC ${INC} ../../../extern/lzo/minilzo)
|
||||||
|
ADD_DEFINITIONS(-DWITH_LZO)
|
||||||
|
ENDIF(WITH_LZO)
|
||||||
|
|
||||||
|
IF(WITH_LZMA)
|
||||||
|
SET(INC ${INC} ../../../extern/lzma)
|
||||||
|
ADD_DEFINITIONS(-DWITH_LZMA)
|
||||||
|
ENDIF(WITH_LZMA)
|
||||||
|
|
||||||
|
IF(WITH_OPENMP)
|
||||||
|
ADD_DEFINITIONS(-DPARALLEL=1)
|
||||||
|
ENDIF(WITH_OPENMP)
|
||||||
|
|
||||||
|
IF(NOT WITH_ELBEEM)
|
||||||
|
ADD_DEFINITIONS(-DDISABLE_ELBEEM)
|
||||||
|
ENDIF(NOT WITH_ELBEEM)
|
||||||
|
|
||||||
|
BLENDERLIB(bf_modifiers "${SRC}" "${INC}")
|
||||||
|
|
||||||
71
source/blender/modifiers/MOD_modifiertypes.h
Normal file
71
source/blender/modifiers/MOD_modifiertypes.h
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful;
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation;
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contributor(s): Ben Batt
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MOD_MODIFIERTYPES_H
|
||||||
|
#define MOD_MODIFIERTYPES_H
|
||||||
|
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
|
||||||
|
/* ****************** Type structures for all modifiers ****************** */
|
||||||
|
|
||||||
|
extern ModifierTypeInfo modifierType_None;
|
||||||
|
extern ModifierTypeInfo modifierType_Subsurf;
|
||||||
|
extern ModifierTypeInfo modifierType_Lattice;
|
||||||
|
extern ModifierTypeInfo modifierType_Curve;
|
||||||
|
extern ModifierTypeInfo modifierType_Build;
|
||||||
|
extern ModifierTypeInfo modifierType_Mirror;
|
||||||
|
extern ModifierTypeInfo modifierType_Decimate;
|
||||||
|
extern ModifierTypeInfo modifierType_Wave;
|
||||||
|
extern ModifierTypeInfo modifierType_Armature;
|
||||||
|
extern ModifierTypeInfo modifierType_Hook;
|
||||||
|
extern ModifierTypeInfo modifierType_Softbody;
|
||||||
|
extern ModifierTypeInfo modifierType_Boolean;
|
||||||
|
extern ModifierTypeInfo modifierType_Array;
|
||||||
|
extern ModifierTypeInfo modifierType_EdgeSplit;
|
||||||
|
extern ModifierTypeInfo modifierType_Displace;
|
||||||
|
extern ModifierTypeInfo modifierType_UVProject;
|
||||||
|
extern ModifierTypeInfo modifierType_Smooth;
|
||||||
|
extern ModifierTypeInfo modifierType_Cast;
|
||||||
|
extern ModifierTypeInfo modifierType_MeshDeform;
|
||||||
|
extern ModifierTypeInfo modifierType_ParticleSystem;
|
||||||
|
extern ModifierTypeInfo modifierType_ParticleInstance;
|
||||||
|
extern ModifierTypeInfo modifierType_Explode;
|
||||||
|
extern ModifierTypeInfo modifierType_Cloth;
|
||||||
|
extern ModifierTypeInfo modifierType_Collision;
|
||||||
|
extern ModifierTypeInfo modifierType_Bevel;
|
||||||
|
extern ModifierTypeInfo modifierType_Shrinkwrap;
|
||||||
|
extern ModifierTypeInfo modifierType_Fluidsim;
|
||||||
|
extern ModifierTypeInfo modifierType_Mask;
|
||||||
|
extern ModifierTypeInfo modifierType_SimpleDeform;
|
||||||
|
extern ModifierTypeInfo modifierType_Multires;
|
||||||
|
extern ModifierTypeInfo modifierType_Surface;
|
||||||
|
extern ModifierTypeInfo modifierType_Smoke;
|
||||||
|
extern ModifierTypeInfo modifierType_ShapeKey;
|
||||||
|
extern ModifierTypeInfo modifierType_Solidify;
|
||||||
|
extern ModifierTypeInfo modifierType_Screw;
|
||||||
|
|
||||||
|
#endif //MOD_MODIFIERTYPES_H
|
||||||
34
source/blender/modifiers/Makefile
Normal file
34
source/blender/modifiers/Makefile
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# $Id:
|
||||||
|
#
|
||||||
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The Original Code is: all of this file.
|
||||||
|
#
|
||||||
|
# Contributor(s): Ben Batt
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# Bounces make to subdirectories.
|
||||||
|
|
||||||
|
SOURCEDIR = source/blender/modifiers
|
||||||
|
DIRS = intern
|
||||||
|
|
||||||
|
include nan_subdirs.mk
|
||||||
17
source/blender/modifiers/SConscript
Normal file
17
source/blender/modifiers/SConscript
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
Import ('env')
|
||||||
|
|
||||||
|
sources = env.Glob('intern/*.c')
|
||||||
|
|
||||||
|
incs = '. ./intern'
|
||||||
|
incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern'
|
||||||
|
incs += ' ../render/extern/include'
|
||||||
|
incs += ' ../include ../blenlib ../makesdna ../blenkernel ../blenkernel/intern'
|
||||||
|
|
||||||
|
incs += ' ' + env['BF_ZLIB_INC']
|
||||||
|
|
||||||
|
defs = ''
|
||||||
|
|
||||||
|
env.BlenderLib ( libname = 'modifiers', sources = sources,
|
||||||
|
includes = Split(incs), defines = Split(defs),
|
||||||
|
libtype=['core','player'], priority = [180, 20] )
|
||||||
219
source/blender/modifiers/intern/MOD_armature.c
Normal file
219
source/blender/modifiers/intern/MOD_armature.c
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Armature */
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
|
||||||
|
amd->deformflag = ARM_DEF_ENVELOPE | ARM_DEF_VGROUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
ArmatureModifierData *tamd = (ArmatureModifierData*) target;
|
||||||
|
|
||||||
|
tamd->object = amd->object;
|
||||||
|
tamd->deformflag = amd->deformflag;
|
||||||
|
strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups */
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
|
||||||
|
return !amd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &amd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
|
||||||
|
if (amd->object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, amd->object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Armature Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
|
||||||
|
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
|
||||||
|
|
||||||
|
armature_deform_verts(amd->object, ob, derivedData, vertexCos, NULL,
|
||||||
|
numVerts, amd->deformflag,
|
||||||
|
(float(*)[3])amd->prevCos, amd->defgrp_name);
|
||||||
|
/* free cache */
|
||||||
|
if(amd->prevCos) {
|
||||||
|
MEM_freeN(amd->prevCos);
|
||||||
|
amd->prevCos= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
|
||||||
|
armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts,
|
||||||
|
amd->deformflag, NULL, amd->defgrp_name);
|
||||||
|
|
||||||
|
if(!derivedData) dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformMatricesEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3],
|
||||||
|
float (*defMats)[3][3], int numVerts)
|
||||||
|
{
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
|
||||||
|
armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts,
|
||||||
|
amd->deformflag, NULL, amd->defgrp_name);
|
||||||
|
|
||||||
|
if(!derivedData) dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Armature = {
|
||||||
|
/* name */ "Armature",
|
||||||
|
/* structName */ "ArmatureModifierData",
|
||||||
|
/* structSize */ sizeof(ArmatureModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ deformMatricesEM,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
813
source/blender/modifiers/intern/MOD_array.c
Normal file
813
source/blender/modifiers/intern/MOD_array.c
Normal file
@@ -0,0 +1,813 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
/* Array */
|
||||||
|
/* Array modifier: duplicates the object multiple times along an axis
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ArrayModifierData *amd = (ArrayModifierData*) md;
|
||||||
|
|
||||||
|
/* default to 2 duplicates distributed along the x-axis by an
|
||||||
|
offset of 1 object-width
|
||||||
|
*/
|
||||||
|
amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
|
||||||
|
amd->count = 2;
|
||||||
|
amd->offset[0] = amd->offset[1] = amd->offset[2] = 0;
|
||||||
|
amd->scale[0] = 1;
|
||||||
|
amd->scale[1] = amd->scale[2] = 0;
|
||||||
|
amd->length = 0;
|
||||||
|
amd->merge_dist = 0.01;
|
||||||
|
amd->fit_type = MOD_ARR_FIXEDCOUNT;
|
||||||
|
amd->offset_type = MOD_ARR_OFF_RELATIVE;
|
||||||
|
amd->flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ArrayModifierData *amd = (ArrayModifierData*) md;
|
||||||
|
ArrayModifierData *tamd = (ArrayModifierData*) target;
|
||||||
|
|
||||||
|
tamd->start_cap = amd->start_cap;
|
||||||
|
tamd->end_cap = amd->end_cap;
|
||||||
|
tamd->curve_ob = amd->curve_ob;
|
||||||
|
tamd->offset_ob = amd->offset_ob;
|
||||||
|
tamd->count = amd->count;
|
||||||
|
VECCOPY(tamd->offset, amd->offset);
|
||||||
|
VECCOPY(tamd->scale, amd->scale);
|
||||||
|
tamd->length = amd->length;
|
||||||
|
tamd->merge_dist = amd->merge_dist;
|
||||||
|
tamd->fit_type = amd->fit_type;
|
||||||
|
tamd->offset_type = amd->offset_type;
|
||||||
|
tamd->flags = amd->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
ArrayModifierData *amd = (ArrayModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &amd->start_cap);
|
||||||
|
walk(userData, ob, &amd->end_cap);
|
||||||
|
walk(userData, ob, &amd->curve_ob);
|
||||||
|
walk(userData, ob, &amd->offset_ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
ArrayModifierData *amd = (ArrayModifierData*) md;
|
||||||
|
|
||||||
|
if (amd->start_cap) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, amd->start_cap);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
|
||||||
|
}
|
||||||
|
if (amd->end_cap) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, amd->end_cap);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
|
||||||
|
}
|
||||||
|
if (amd->curve_ob) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, amd->curve_ob);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
|
||||||
|
}
|
||||||
|
if (amd->offset_ob) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, amd->offset_ob);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float vertarray_size(MVert *mvert, int numVerts, int axis)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float min_co, max_co;
|
||||||
|
|
||||||
|
/* if there are no vertices, width is 0 */
|
||||||
|
if(numVerts == 0) return 0;
|
||||||
|
|
||||||
|
/* find the minimum and maximum coordinates on the desired axis */
|
||||||
|
min_co = max_co = mvert->co[axis];
|
||||||
|
++mvert;
|
||||||
|
for(i = 1; i < numVerts; ++i, ++mvert) {
|
||||||
|
if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
|
||||||
|
if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_co - min_co;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct IndexMapEntry {
|
||||||
|
/* the new vert index that this old vert index maps to */
|
||||||
|
int new;
|
||||||
|
/* -1 if this vert isn't merged, otherwise the old vert index it
|
||||||
|
* should be replaced with
|
||||||
|
*/
|
||||||
|
int merge;
|
||||||
|
/* 1 if this vert's first copy is merged with the last copy of its
|
||||||
|
* merge target, otherwise 0
|
||||||
|
*/
|
||||||
|
short merge_final;
|
||||||
|
} IndexMapEntry;
|
||||||
|
|
||||||
|
/* indexMap - an array of IndexMap entries
|
||||||
|
* oldIndex - the old index to map
|
||||||
|
* copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
|
||||||
|
*/
|
||||||
|
static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
|
||||||
|
{
|
||||||
|
if(indexMap[oldIndex].merge < 0) {
|
||||||
|
/* vert wasn't merged, so use copy of this vert */
|
||||||
|
return indexMap[oldIndex].new + copyNum;
|
||||||
|
} else if(indexMap[oldIndex].merge == oldIndex) {
|
||||||
|
/* vert was merged with itself */
|
||||||
|
return indexMap[oldIndex].new;
|
||||||
|
} else {
|
||||||
|
/* vert was merged with another vert */
|
||||||
|
/* follow the chain of merges to the end, or until we've passed
|
||||||
|
* a number of vertices equal to the copy number
|
||||||
|
*/
|
||||||
|
if(copyNum <= 0)
|
||||||
|
return indexMap[oldIndex].new;
|
||||||
|
else
|
||||||
|
return calc_mapping(indexMap, indexMap[oldIndex].merge,
|
||||||
|
copyNum - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|
||||||
|
Scene *scene, Object *ob, DerivedMesh *dm,
|
||||||
|
int initFlags)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
/* offset matrix */
|
||||||
|
float offset[4][4];
|
||||||
|
float final_offset[4][4];
|
||||||
|
float tmp_mat[4][4];
|
||||||
|
float length = amd->length;
|
||||||
|
int count = amd->count;
|
||||||
|
int numVerts, numEdges, numFaces;
|
||||||
|
int maxVerts, maxEdges, maxFaces;
|
||||||
|
int finalVerts, finalEdges, finalFaces;
|
||||||
|
DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
|
||||||
|
MVert *mvert, *src_mvert;
|
||||||
|
MEdge *medge;
|
||||||
|
MFace *mface;
|
||||||
|
|
||||||
|
IndexMapEntry *indexMap;
|
||||||
|
|
||||||
|
EdgeHash *edges;
|
||||||
|
|
||||||
|
/* need to avoid infinite recursion here */
|
||||||
|
if(amd->start_cap && amd->start_cap != ob)
|
||||||
|
start_cap = amd->start_cap->derivedFinal;
|
||||||
|
if(amd->end_cap && amd->end_cap != ob)
|
||||||
|
end_cap = amd->end_cap->derivedFinal;
|
||||||
|
|
||||||
|
unit_m4(offset);
|
||||||
|
|
||||||
|
indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
|
||||||
|
"indexmap");
|
||||||
|
|
||||||
|
src_mvert = dm->getVertArray(dm);
|
||||||
|
|
||||||
|
maxVerts = dm->getNumVerts(dm);
|
||||||
|
|
||||||
|
if(amd->offset_type & MOD_ARR_OFF_CONST)
|
||||||
|
add_v3_v3v3(offset[3], offset[3], amd->offset);
|
||||||
|
if(amd->offset_type & MOD_ARR_OFF_RELATIVE) {
|
||||||
|
for(j = 0; j < 3; j++)
|
||||||
|
offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
|
||||||
|
maxVerts, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
|
||||||
|
float obinv[4][4];
|
||||||
|
float result_mat[4][4];
|
||||||
|
|
||||||
|
if(ob)
|
||||||
|
invert_m4_m4(obinv, ob->obmat);
|
||||||
|
else
|
||||||
|
unit_m4(obinv);
|
||||||
|
|
||||||
|
mul_serie_m4(result_mat, offset,
|
||||||
|
obinv, amd->offset_ob->obmat,
|
||||||
|
NULL, NULL, NULL, NULL, NULL);
|
||||||
|
copy_m4_m4(offset, result_mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
|
||||||
|
Curve *cu = amd->curve_ob->data;
|
||||||
|
if(cu) {
|
||||||
|
float tmp_mat[3][3];
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
object_to_mat3(amd->curve_ob, tmp_mat);
|
||||||
|
scale = mat3_to_scale(tmp_mat);
|
||||||
|
|
||||||
|
if(!cu->path) {
|
||||||
|
cu->flag |= CU_PATH; // needed for path & bevlist
|
||||||
|
makeDispListCurveTypes(scene, amd->curve_ob, 0);
|
||||||
|
}
|
||||||
|
if(cu->path)
|
||||||
|
length = scale*cu->path->totdist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the maximum number of copies which will fit within the
|
||||||
|
prescribed length */
|
||||||
|
if(amd->fit_type == MOD_ARR_FITLENGTH
|
||||||
|
|| amd->fit_type == MOD_ARR_FITCURVE) {
|
||||||
|
float dist = sqrt(dot_v3v3(offset[3], offset[3]));
|
||||||
|
|
||||||
|
if(dist > 1e-6f)
|
||||||
|
/* this gives length = first copy start to last copy end
|
||||||
|
add a tiny offset for floating point rounding errors */
|
||||||
|
count = (length + 1e-6f) / dist;
|
||||||
|
else
|
||||||
|
/* if the offset has no translation, just make one copy */
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count < 1)
|
||||||
|
count = 1;
|
||||||
|
|
||||||
|
/* allocate memory for count duplicates (including original) plus
|
||||||
|
* start and end caps
|
||||||
|
*/
|
||||||
|
finalVerts = dm->getNumVerts(dm) * count;
|
||||||
|
finalEdges = dm->getNumEdges(dm) * count;
|
||||||
|
finalFaces = dm->getNumFaces(dm) * count;
|
||||||
|
if(start_cap) {
|
||||||
|
finalVerts += start_cap->getNumVerts(start_cap);
|
||||||
|
finalEdges += start_cap->getNumEdges(start_cap);
|
||||||
|
finalFaces += start_cap->getNumFaces(start_cap);
|
||||||
|
}
|
||||||
|
if(end_cap) {
|
||||||
|
finalVerts += end_cap->getNumVerts(end_cap);
|
||||||
|
finalEdges += end_cap->getNumEdges(end_cap);
|
||||||
|
finalFaces += end_cap->getNumFaces(end_cap);
|
||||||
|
}
|
||||||
|
result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
|
||||||
|
|
||||||
|
/* calculate the offset matrix of the final copy (for merging) */
|
||||||
|
unit_m4(final_offset);
|
||||||
|
|
||||||
|
for(j=0; j < count - 1; j++) {
|
||||||
|
mul_m4_m4m4(tmp_mat, final_offset, offset);
|
||||||
|
copy_m4_m4(final_offset, tmp_mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
numVerts = numEdges = numFaces = 0;
|
||||||
|
mvert = CDDM_get_verts(result);
|
||||||
|
|
||||||
|
for (i = 0; i < maxVerts; i++) {
|
||||||
|
indexMap[i].merge = -1; /* default to no merge */
|
||||||
|
indexMap[i].merge_final = 0; /* default to no merge */
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < maxVerts; i++) {
|
||||||
|
MVert *inMV;
|
||||||
|
MVert *mv = &mvert[numVerts];
|
||||||
|
MVert *mv2;
|
||||||
|
float co[3];
|
||||||
|
|
||||||
|
inMV = &src_mvert[i];
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm, result, i, numVerts, 1);
|
||||||
|
*mv = *inMV;
|
||||||
|
numVerts++;
|
||||||
|
|
||||||
|
indexMap[i].new = numVerts - 1;
|
||||||
|
|
||||||
|
VECCOPY(co, mv->co);
|
||||||
|
|
||||||
|
/* Attempts to merge verts from one duplicate with verts from the
|
||||||
|
* next duplicate which are closer than amd->merge_dist.
|
||||||
|
* Only the first such vert pair is merged.
|
||||||
|
* If verts are merged in the first duplicate pair, they are merged
|
||||||
|
* in all pairs.
|
||||||
|
*/
|
||||||
|
if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
|
||||||
|
float tmp_co[3];
|
||||||
|
VECCOPY(tmp_co, mv->co);
|
||||||
|
mul_m4_v3(offset, tmp_co);
|
||||||
|
|
||||||
|
for(j = 0; j < maxVerts; j++) {
|
||||||
|
/* if vertex already merged, don't use it */
|
||||||
|
if( indexMap[j].merge != -1 ) continue;
|
||||||
|
|
||||||
|
inMV = &src_mvert[j];
|
||||||
|
/* if this vert is within merge limit, merge */
|
||||||
|
if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) {
|
||||||
|
indexMap[i].merge = j;
|
||||||
|
|
||||||
|
/* test for merging with final copy of merge target */
|
||||||
|
if(amd->flags & MOD_ARR_MERGEFINAL) {
|
||||||
|
VECCOPY(tmp_co, inMV->co);
|
||||||
|
inMV = &src_mvert[i];
|
||||||
|
mul_m4_v3(final_offset, tmp_co);
|
||||||
|
if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist))
|
||||||
|
indexMap[i].merge_final = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no merging, generate copies of this vert */
|
||||||
|
if(indexMap[i].merge < 0) {
|
||||||
|
for(j=0; j < count - 1; j++) {
|
||||||
|
mv2 = &mvert[numVerts];
|
||||||
|
|
||||||
|
DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1);
|
||||||
|
*mv2 = *mv;
|
||||||
|
numVerts++;
|
||||||
|
|
||||||
|
mul_m4_v3(offset, co);
|
||||||
|
VECCOPY(mv2->co, co);
|
||||||
|
}
|
||||||
|
} else if(indexMap[i].merge != i && indexMap[i].merge_final) {
|
||||||
|
/* if this vert is not merging with itself, and it is merging
|
||||||
|
* with the final copy of its merge target, remove the first copy
|
||||||
|
*/
|
||||||
|
numVerts--;
|
||||||
|
DM_free_vert_data(result, numVerts, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make a hashtable so we can avoid duplicate edges from merging */
|
||||||
|
edges = BLI_edgehash_new();
|
||||||
|
|
||||||
|
maxEdges = dm->getNumEdges(dm);
|
||||||
|
medge = CDDM_get_edges(result);
|
||||||
|
for(i = 0; i < maxEdges; i++) {
|
||||||
|
MEdge inMED;
|
||||||
|
MEdge med;
|
||||||
|
MEdge *med2;
|
||||||
|
int vert1, vert2;
|
||||||
|
|
||||||
|
dm->getEdge(dm, i, &inMED);
|
||||||
|
|
||||||
|
med = inMED;
|
||||||
|
med.v1 = indexMap[inMED.v1].new;
|
||||||
|
med.v2 = indexMap[inMED.v2].new;
|
||||||
|
|
||||||
|
/* if vertices are to be merged with the final copies of their
|
||||||
|
* merge targets, calculate that final copy
|
||||||
|
*/
|
||||||
|
if(indexMap[inMED.v1].merge_final) {
|
||||||
|
med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge,
|
||||||
|
count - 1);
|
||||||
|
}
|
||||||
|
if(indexMap[inMED.v2].merge_final) {
|
||||||
|
med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge,
|
||||||
|
count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(med.v1 == med.v2) continue;
|
||||||
|
|
||||||
|
if (initFlags) {
|
||||||
|
med.flag |= ME_EDGEDRAW | ME_EDGERENDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) {
|
||||||
|
DM_copy_edge_data(dm, result, i, numEdges, 1);
|
||||||
|
medge[numEdges] = med;
|
||||||
|
numEdges++;
|
||||||
|
|
||||||
|
BLI_edgehash_insert(edges, med.v1, med.v2, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j = 1; j < count; j++)
|
||||||
|
{
|
||||||
|
vert1 = calc_mapping(indexMap, inMED.v1, j);
|
||||||
|
vert2 = calc_mapping(indexMap, inMED.v2, j);
|
||||||
|
/* avoid duplicate edges */
|
||||||
|
if(!BLI_edgehash_haskey(edges, vert1, vert2)) {
|
||||||
|
med2 = &medge[numEdges];
|
||||||
|
|
||||||
|
DM_copy_edge_data(dm, result, i, numEdges, 1);
|
||||||
|
*med2 = med;
|
||||||
|
numEdges++;
|
||||||
|
|
||||||
|
med2->v1 = vert1;
|
||||||
|
med2->v2 = vert2;
|
||||||
|
|
||||||
|
BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maxFaces = dm->getNumFaces(dm);
|
||||||
|
mface = CDDM_get_faces(result);
|
||||||
|
for (i=0; i < maxFaces; i++) {
|
||||||
|
MFace inMF;
|
||||||
|
MFace *mf = &mface[numFaces];
|
||||||
|
|
||||||
|
dm->getFace(dm, i, &inMF);
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, i, numFaces, 1);
|
||||||
|
*mf = inMF;
|
||||||
|
|
||||||
|
mf->v1 = indexMap[inMF.v1].new;
|
||||||
|
mf->v2 = indexMap[inMF.v2].new;
|
||||||
|
mf->v3 = indexMap[inMF.v3].new;
|
||||||
|
if(inMF.v4)
|
||||||
|
mf->v4 = indexMap[inMF.v4].new;
|
||||||
|
|
||||||
|
/* if vertices are to be merged with the final copies of their
|
||||||
|
* merge targets, calculate that final copy
|
||||||
|
*/
|
||||||
|
if(indexMap[inMF.v1].merge_final)
|
||||||
|
mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1);
|
||||||
|
if(indexMap[inMF.v2].merge_final)
|
||||||
|
mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1);
|
||||||
|
if(indexMap[inMF.v3].merge_final)
|
||||||
|
mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1);
|
||||||
|
if(inMF.v4 && indexMap[inMF.v4].merge_final)
|
||||||
|
mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1);
|
||||||
|
|
||||||
|
if(test_index_face(mf, &result->faceData, numFaces, inMF.v4?4:3) < 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
numFaces++;
|
||||||
|
|
||||||
|
/* if the face has fewer than 3 vertices, don't create it */
|
||||||
|
if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) {
|
||||||
|
numFaces--;
|
||||||
|
DM_free_face_data(result, numFaces, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j = 1; j < count; j++)
|
||||||
|
{
|
||||||
|
MFace *mf2 = &mface[numFaces];
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, i, numFaces, 1);
|
||||||
|
*mf2 = *mf;
|
||||||
|
|
||||||
|
mf2->v1 = calc_mapping(indexMap, inMF.v1, j);
|
||||||
|
mf2->v2 = calc_mapping(indexMap, inMF.v2, j);
|
||||||
|
mf2->v3 = calc_mapping(indexMap, inMF.v3, j);
|
||||||
|
if (inMF.v4)
|
||||||
|
mf2->v4 = calc_mapping(indexMap, inMF.v4, j);
|
||||||
|
|
||||||
|
test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
|
||||||
|
numFaces++;
|
||||||
|
|
||||||
|
/* if the face has fewer than 3 vertices, don't create it */
|
||||||
|
if(mf2->v3 == 0 || (mf2->v1 && (mf2->v1 == mf2->v3 || mf2->v1 ==
|
||||||
|
mf2->v4))) {
|
||||||
|
numFaces--;
|
||||||
|
DM_free_face_data(result, numFaces, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add start and end caps */
|
||||||
|
if(start_cap) {
|
||||||
|
float startoffset[4][4];
|
||||||
|
MVert *cap_mvert;
|
||||||
|
MEdge *cap_medge;
|
||||||
|
MFace *cap_mface;
|
||||||
|
int *origindex;
|
||||||
|
int *vert_map;
|
||||||
|
int capVerts, capEdges, capFaces;
|
||||||
|
|
||||||
|
capVerts = start_cap->getNumVerts(start_cap);
|
||||||
|
capEdges = start_cap->getNumEdges(start_cap);
|
||||||
|
capFaces = start_cap->getNumFaces(start_cap);
|
||||||
|
cap_mvert = start_cap->getVertArray(start_cap);
|
||||||
|
cap_medge = start_cap->getEdgeArray(start_cap);
|
||||||
|
cap_mface = start_cap->getFaceArray(start_cap);
|
||||||
|
|
||||||
|
invert_m4_m4(startoffset, offset);
|
||||||
|
|
||||||
|
vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
|
||||||
|
"arrayModifier_doArray vert_map");
|
||||||
|
|
||||||
|
origindex = result->getVertDataArray(result, CD_ORIGINDEX);
|
||||||
|
for(i = 0; i < capVerts; i++) {
|
||||||
|
MVert *mv = &cap_mvert[i];
|
||||||
|
short merged = 0;
|
||||||
|
|
||||||
|
if(amd->flags & MOD_ARR_MERGE) {
|
||||||
|
float tmp_co[3];
|
||||||
|
MVert *in_mv;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
VECCOPY(tmp_co, mv->co);
|
||||||
|
mul_m4_v3(startoffset, tmp_co);
|
||||||
|
|
||||||
|
for(j = 0; j < maxVerts; j++) {
|
||||||
|
in_mv = &src_mvert[j];
|
||||||
|
/* if this vert is within merge limit, merge */
|
||||||
|
if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
|
||||||
|
vert_map[i] = calc_mapping(indexMap, j, 0);
|
||||||
|
merged = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!merged) {
|
||||||
|
DM_copy_vert_data(start_cap, result, i, numVerts, 1);
|
||||||
|
mvert[numVerts] = *mv;
|
||||||
|
mul_m4_v3(startoffset, mvert[numVerts].co);
|
||||||
|
origindex[numVerts] = ORIGINDEX_NONE;
|
||||||
|
|
||||||
|
vert_map[i] = numVerts;
|
||||||
|
|
||||||
|
numVerts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
|
||||||
|
for(i = 0; i < capEdges; i++) {
|
||||||
|
int v1, v2;
|
||||||
|
|
||||||
|
v1 = vert_map[cap_medge[i].v1];
|
||||||
|
v2 = vert_map[cap_medge[i].v2];
|
||||||
|
|
||||||
|
if(!BLI_edgehash_haskey(edges, v1, v2)) {
|
||||||
|
DM_copy_edge_data(start_cap, result, i, numEdges, 1);
|
||||||
|
medge[numEdges] = cap_medge[i];
|
||||||
|
medge[numEdges].v1 = v1;
|
||||||
|
medge[numEdges].v2 = v2;
|
||||||
|
origindex[numEdges] = ORIGINDEX_NONE;
|
||||||
|
|
||||||
|
numEdges++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
|
||||||
|
for(i = 0; i < capFaces; i++) {
|
||||||
|
DM_copy_face_data(start_cap, result, i, numFaces, 1);
|
||||||
|
mface[numFaces] = cap_mface[i];
|
||||||
|
mface[numFaces].v1 = vert_map[mface[numFaces].v1];
|
||||||
|
mface[numFaces].v2 = vert_map[mface[numFaces].v2];
|
||||||
|
mface[numFaces].v3 = vert_map[mface[numFaces].v3];
|
||||||
|
if(mface[numFaces].v4) {
|
||||||
|
mface[numFaces].v4 = vert_map[mface[numFaces].v4];
|
||||||
|
|
||||||
|
test_index_face(&mface[numFaces], &result->faceData,
|
||||||
|
numFaces, 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
test_index_face(&mface[numFaces], &result->faceData,
|
||||||
|
numFaces, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
origindex[numFaces] = ORIGINDEX_NONE;
|
||||||
|
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(vert_map);
|
||||||
|
start_cap->release(start_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(end_cap) {
|
||||||
|
float endoffset[4][4];
|
||||||
|
MVert *cap_mvert;
|
||||||
|
MEdge *cap_medge;
|
||||||
|
MFace *cap_mface;
|
||||||
|
int *origindex;
|
||||||
|
int *vert_map;
|
||||||
|
int capVerts, capEdges, capFaces;
|
||||||
|
|
||||||
|
capVerts = end_cap->getNumVerts(end_cap);
|
||||||
|
capEdges = end_cap->getNumEdges(end_cap);
|
||||||
|
capFaces = end_cap->getNumFaces(end_cap);
|
||||||
|
cap_mvert = end_cap->getVertArray(end_cap);
|
||||||
|
cap_medge = end_cap->getEdgeArray(end_cap);
|
||||||
|
cap_mface = end_cap->getFaceArray(end_cap);
|
||||||
|
|
||||||
|
mul_m4_m4m4(endoffset, final_offset, offset);
|
||||||
|
|
||||||
|
vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
|
||||||
|
"arrayModifier_doArray vert_map");
|
||||||
|
|
||||||
|
origindex = result->getVertDataArray(result, CD_ORIGINDEX);
|
||||||
|
for(i = 0; i < capVerts; i++) {
|
||||||
|
MVert *mv = &cap_mvert[i];
|
||||||
|
short merged = 0;
|
||||||
|
|
||||||
|
if(amd->flags & MOD_ARR_MERGE) {
|
||||||
|
float tmp_co[3];
|
||||||
|
MVert *in_mv;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
VECCOPY(tmp_co, mv->co);
|
||||||
|
mul_m4_v3(offset, tmp_co);
|
||||||
|
|
||||||
|
for(j = 0; j < maxVerts; j++) {
|
||||||
|
in_mv = &src_mvert[j];
|
||||||
|
/* if this vert is within merge limit, merge */
|
||||||
|
if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
|
||||||
|
vert_map[i] = calc_mapping(indexMap, j, count - 1);
|
||||||
|
merged = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!merged) {
|
||||||
|
DM_copy_vert_data(end_cap, result, i, numVerts, 1);
|
||||||
|
mvert[numVerts] = *mv;
|
||||||
|
mul_m4_v3(endoffset, mvert[numVerts].co);
|
||||||
|
origindex[numVerts] = ORIGINDEX_NONE;
|
||||||
|
|
||||||
|
vert_map[i] = numVerts;
|
||||||
|
|
||||||
|
numVerts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
|
||||||
|
for(i = 0; i < capEdges; i++) {
|
||||||
|
int v1, v2;
|
||||||
|
|
||||||
|
v1 = vert_map[cap_medge[i].v1];
|
||||||
|
v2 = vert_map[cap_medge[i].v2];
|
||||||
|
|
||||||
|
if(!BLI_edgehash_haskey(edges, v1, v2)) {
|
||||||
|
DM_copy_edge_data(end_cap, result, i, numEdges, 1);
|
||||||
|
medge[numEdges] = cap_medge[i];
|
||||||
|
medge[numEdges].v1 = v1;
|
||||||
|
medge[numEdges].v2 = v2;
|
||||||
|
origindex[numEdges] = ORIGINDEX_NONE;
|
||||||
|
|
||||||
|
numEdges++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
|
||||||
|
for(i = 0; i < capFaces; i++) {
|
||||||
|
DM_copy_face_data(end_cap, result, i, numFaces, 1);
|
||||||
|
mface[numFaces] = cap_mface[i];
|
||||||
|
mface[numFaces].v1 = vert_map[mface[numFaces].v1];
|
||||||
|
mface[numFaces].v2 = vert_map[mface[numFaces].v2];
|
||||||
|
mface[numFaces].v3 = vert_map[mface[numFaces].v3];
|
||||||
|
if(mface[numFaces].v4) {
|
||||||
|
mface[numFaces].v4 = vert_map[mface[numFaces].v4];
|
||||||
|
|
||||||
|
test_index_face(&mface[numFaces], &result->faceData,
|
||||||
|
numFaces, 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
test_index_face(&mface[numFaces], &result->faceData,
|
||||||
|
numFaces, 3);
|
||||||
|
}
|
||||||
|
origindex[numFaces] = ORIGINDEX_NONE;
|
||||||
|
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(vert_map);
|
||||||
|
end_cap->release(end_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_edgehash_free(edges, NULL);
|
||||||
|
MEM_freeN(indexMap);
|
||||||
|
|
||||||
|
CDDM_lower_num_verts(result, numVerts);
|
||||||
|
CDDM_lower_num_edges(result, numEdges);
|
||||||
|
CDDM_lower_num_faces(result, numFaces);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *result;
|
||||||
|
ArrayModifierData *amd = (ArrayModifierData*) md;
|
||||||
|
|
||||||
|
result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
|
||||||
|
|
||||||
|
if(result != derivedData)
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Array = {
|
||||||
|
/* name */ "Array",
|
||||||
|
/* structName */ "ArrayModifierData",
|
||||||
|
/* structSize */ sizeof(ArrayModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_SupportsMapping
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode
|
||||||
|
| eModifierTypeFlag_AcceptsCVs,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
184
source/blender/modifiers/intern/MOD_bevel.c
Normal file
184
source/blender/modifiers/intern/MOD_bevel.c
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
BevelModifierData *bmd = (BevelModifierData*) md;
|
||||||
|
|
||||||
|
bmd->value = 0.1f;
|
||||||
|
bmd->res = 1;
|
||||||
|
bmd->flags = 0;
|
||||||
|
bmd->val_flags = 0;
|
||||||
|
bmd->lim_flags = 0;
|
||||||
|
bmd->e_flags = 0;
|
||||||
|
bmd->bevel_angle = 30;
|
||||||
|
bmd->defgrp_name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
BevelModifierData *bmd = (BevelModifierData*) md;
|
||||||
|
BevelModifierData *tbmd = (BevelModifierData*) target;
|
||||||
|
|
||||||
|
tbmd->value = bmd->value;
|
||||||
|
tbmd->res = bmd->res;
|
||||||
|
tbmd->flags = bmd->flags;
|
||||||
|
tbmd->val_flags = bmd->val_flags;
|
||||||
|
tbmd->lim_flags = bmd->lim_flags;
|
||||||
|
tbmd->e_flags = bmd->e_flags;
|
||||||
|
tbmd->bevel_angle = bmd->bevel_angle;
|
||||||
|
strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
BevelModifierData *bmd = (BevelModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(bmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *result;
|
||||||
|
BME_Mesh *bm;
|
||||||
|
|
||||||
|
/*bDeformGroup *def;*/
|
||||||
|
int /*i,*/ options, defgrp_index = -1;
|
||||||
|
BevelModifierData *bmd = (BevelModifierData*) md;
|
||||||
|
|
||||||
|
options = bmd->flags|bmd->val_flags|bmd->lim_flags|bmd->e_flags;
|
||||||
|
|
||||||
|
/*if ((options & BME_BEVEL_VWEIGHT) && bmd->defgrp_name[0]) {
|
||||||
|
defgrp_index = defgroup_name_index(ob, bmd->defgrp_name);
|
||||||
|
if (defgrp_index < 0) {
|
||||||
|
options &= ~BME_BEVEL_VWEIGHT;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
bm = BME_derivedmesh_to_bmesh(derivedData);
|
||||||
|
BME_bevel(bm,bmd->value,bmd->res,options,defgrp_index,bmd->bevel_angle,NULL);
|
||||||
|
result = BME_bmesh_to_derivedmesh(bm,derivedData);
|
||||||
|
BME_free_mesh(bm);
|
||||||
|
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Bevel = {
|
||||||
|
/* name */ "Bevel",
|
||||||
|
/* structName */ "BevelModifierData",
|
||||||
|
/* structSize */ sizeof(BevelModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
182
source/blender/modifiers/intern/MOD_boolean.c
Normal file
182
source/blender/modifiers/intern/MOD_boolean.c
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_boolean_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
BooleanModifierData *bmd = (BooleanModifierData*) md;
|
||||||
|
BooleanModifierData *tbmd = (BooleanModifierData*) target;
|
||||||
|
|
||||||
|
tbmd->object = bmd->object;
|
||||||
|
tbmd->operation = bmd->operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
BooleanModifierData *bmd = (BooleanModifierData*) md;
|
||||||
|
|
||||||
|
return !bmd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
BooleanModifierData *bmd = (BooleanModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &bmd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
BooleanModifierData *bmd = (BooleanModifierData*) md;
|
||||||
|
|
||||||
|
if(bmd->object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, bmd->object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Boolean Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
BooleanModifierData *bmd = (BooleanModifierData*) md;
|
||||||
|
DerivedMesh *dm = bmd->object->derivedFinal;
|
||||||
|
|
||||||
|
/* we do a quick sanity check */
|
||||||
|
if(dm && (derivedData->getNumFaces(derivedData) > 3)
|
||||||
|
&& bmd->object && dm->getNumFaces(dm) > 3) {
|
||||||
|
DerivedMesh *result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
|
||||||
|
1 + bmd->operation);
|
||||||
|
|
||||||
|
/* if new mesh returned, return it; otherwise there was
|
||||||
|
* an error, so delete the modifier object */
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
else
|
||||||
|
modifier_setError(md, "Can't execute boolean operation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
|
||||||
|
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Boolean = {
|
||||||
|
/* name */ "Boolean",
|
||||||
|
/* structName */ "BooleanModifierData",
|
||||||
|
/* structSize */ sizeof(BooleanModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_UsesPointCache,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
594
source/blender/modifiers/intern/MOD_boolean_util.c
Normal file
594
source/blender/modifiers/intern/MOD_boolean_util.c
Normal file
@@ -0,0 +1,594 @@
|
|||||||
|
/**
|
||||||
|
* $Id: booleanops.c 27655 2010-03-22 09:30:00Z campbellbarton $
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) Blender Foundation
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
* CSG operations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "BLI_math.h"
|
||||||
|
#include "BLI_ghash.h"
|
||||||
|
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_mesh_types.h"
|
||||||
|
#include "DNA_meshdata_types.h"
|
||||||
|
#include "DNA_object_types.h"
|
||||||
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "CSG_BooleanOps.h"
|
||||||
|
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_depsgraph.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here's the vertex iterator structure used to walk through
|
||||||
|
* the blender vertex structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DerivedMesh *dm;
|
||||||
|
Object *ob;
|
||||||
|
int pos;
|
||||||
|
} VertexIt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementations of local vertex iterator functions.
|
||||||
|
* These describe a blender mesh to the CSG module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void VertexIt_Destruct(CSG_VertexIteratorDescriptor * iterator)
|
||||||
|
{
|
||||||
|
if (iterator->it) {
|
||||||
|
// deallocate memory for iterator
|
||||||
|
MEM_freeN(iterator->it);
|
||||||
|
iterator->it = 0;
|
||||||
|
}
|
||||||
|
iterator->Done = NULL;
|
||||||
|
iterator->Fill = NULL;
|
||||||
|
iterator->Reset = NULL;
|
||||||
|
iterator->Step = NULL;
|
||||||
|
iterator->num_elements = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int VertexIt_Done(CSG_IteratorPtr it)
|
||||||
|
{
|
||||||
|
VertexIt * iterator = (VertexIt *)it;
|
||||||
|
return(iterator->pos >= iterator->dm->getNumVerts(iterator->dm));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert)
|
||||||
|
{
|
||||||
|
VertexIt * iterator = (VertexIt *)it;
|
||||||
|
MVert *verts = iterator->dm->getVertArray(iterator->dm);
|
||||||
|
|
||||||
|
float global_pos[3];
|
||||||
|
|
||||||
|
/* boolean happens in global space, transform both with obmat */
|
||||||
|
mul_v3_m4v3(
|
||||||
|
global_pos,
|
||||||
|
iterator->ob->obmat,
|
||||||
|
verts[iterator->pos].co
|
||||||
|
);
|
||||||
|
|
||||||
|
vert->position[0] = global_pos[0];
|
||||||
|
vert->position[1] = global_pos[1];
|
||||||
|
vert->position[2] = global_pos[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VertexIt_Step(CSG_IteratorPtr it)
|
||||||
|
{
|
||||||
|
VertexIt * iterator = (VertexIt *)it;
|
||||||
|
iterator->pos ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VertexIt_Reset(CSG_IteratorPtr it)
|
||||||
|
{
|
||||||
|
VertexIt * iterator = (VertexIt *)it;
|
||||||
|
iterator->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, DerivedMesh *dm, Object *ob)
|
||||||
|
{
|
||||||
|
|
||||||
|
VertexIt *it;
|
||||||
|
if (output == 0) return;
|
||||||
|
|
||||||
|
// allocate some memory for blender iterator
|
||||||
|
it = (VertexIt *)(MEM_mallocN(sizeof(VertexIt),"Boolean_VIt"));
|
||||||
|
if (it == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// assign blender specific variables
|
||||||
|
it->dm = dm;
|
||||||
|
it->ob = ob; // needed for obmat transformations
|
||||||
|
|
||||||
|
it->pos = 0;
|
||||||
|
|
||||||
|
// assign iterator function pointers.
|
||||||
|
output->Step = VertexIt_Step;
|
||||||
|
output->Fill = VertexIt_Fill;
|
||||||
|
output->Done = VertexIt_Done;
|
||||||
|
output->Reset = VertexIt_Reset;
|
||||||
|
output->num_elements = it->dm->getNumVerts(it->dm);
|
||||||
|
output->it = it;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blender Face iterator
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DerivedMesh *dm;
|
||||||
|
int pos;
|
||||||
|
int offset;
|
||||||
|
int flip;
|
||||||
|
} FaceIt;
|
||||||
|
|
||||||
|
static void FaceIt_Destruct(CSG_FaceIteratorDescriptor * iterator)
|
||||||
|
{
|
||||||
|
MEM_freeN(iterator->it);
|
||||||
|
iterator->Done = NULL;
|
||||||
|
iterator->Fill = NULL;
|
||||||
|
iterator->Reset = NULL;
|
||||||
|
iterator->Step = NULL;
|
||||||
|
iterator->num_elements = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FaceIt_Done(CSG_IteratorPtr it)
|
||||||
|
{
|
||||||
|
// assume CSG_IteratorPtr is of the correct type.
|
||||||
|
FaceIt * iterator = (FaceIt *)it;
|
||||||
|
return(iterator->pos >= iterator->dm->getNumFaces(iterator->dm));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face)
|
||||||
|
{
|
||||||
|
// assume CSG_IteratorPtr is of the correct type.
|
||||||
|
FaceIt *face_it = (FaceIt *)it;
|
||||||
|
MFace *mfaces = face_it->dm->getFaceArray(face_it->dm);
|
||||||
|
MFace *mface = &mfaces[face_it->pos];
|
||||||
|
|
||||||
|
/* reverse face vertices if necessary */
|
||||||
|
face->vertex_index[1] = mface->v2;
|
||||||
|
if( face_it->flip == 0 ) {
|
||||||
|
face->vertex_index[0] = mface->v1;
|
||||||
|
face->vertex_index[2] = mface->v3;
|
||||||
|
} else {
|
||||||
|
face->vertex_index[2] = mface->v1;
|
||||||
|
face->vertex_index[0] = mface->v3;
|
||||||
|
}
|
||||||
|
if (mface->v4) {
|
||||||
|
face->vertex_index[3] = mface->v4;
|
||||||
|
face->vertex_number = 4;
|
||||||
|
} else {
|
||||||
|
face->vertex_number = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
face->orig_face = face_it->offset + face_it->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FaceIt_Step(CSG_IteratorPtr it)
|
||||||
|
{
|
||||||
|
FaceIt * face_it = (FaceIt *)it;
|
||||||
|
face_it->pos ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FaceIt_Reset(CSG_IteratorPtr it)
|
||||||
|
{
|
||||||
|
FaceIt * face_it = (FaceIt *)it;
|
||||||
|
face_it->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FaceIt_Construct(
|
||||||
|
CSG_FaceIteratorDescriptor *output, DerivedMesh *dm, int offset, Object *ob)
|
||||||
|
{
|
||||||
|
FaceIt *it;
|
||||||
|
if (output == 0) return;
|
||||||
|
|
||||||
|
// allocate some memory for blender iterator
|
||||||
|
it = (FaceIt *)(MEM_mallocN(sizeof(FaceIt),"Boolean_FIt"));
|
||||||
|
if (it == 0) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
// assign blender specific variables
|
||||||
|
it->dm = dm;
|
||||||
|
it->offset = offset;
|
||||||
|
it->pos = 0;
|
||||||
|
|
||||||
|
/* determine if we will need to reverse order of face vertices */
|
||||||
|
if (ob->size[0] < 0.0f) {
|
||||||
|
if (ob->size[1] < 0.0f && ob->size[2] < 0.0f) {
|
||||||
|
it->flip = 1;
|
||||||
|
} else if (ob->size[1] >= 0.0f && ob->size[2] >= 0.0f) {
|
||||||
|
it->flip = 1;
|
||||||
|
} else {
|
||||||
|
it->flip = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ob->size[1] < 0.0f && ob->size[2] < 0.0f) {
|
||||||
|
it->flip = 0;
|
||||||
|
} else if (ob->size[1] >= 0.0f && ob->size[2] >= 0.0f) {
|
||||||
|
it->flip = 0;
|
||||||
|
} else {
|
||||||
|
it->flip = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign iterator function pointers.
|
||||||
|
output->Step = FaceIt_Step;
|
||||||
|
output->Fill = FaceIt_Fill;
|
||||||
|
output->Done = FaceIt_Done;
|
||||||
|
output->Reset = FaceIt_Reset;
|
||||||
|
output->num_elements = it->dm->getNumFaces(it->dm);
|
||||||
|
output->it = it;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object *AddNewBlenderMesh(Scene *scene, Base *base)
|
||||||
|
{
|
||||||
|
// This little function adds a new mesh object to the blender object list
|
||||||
|
// It uses ob to duplicate data as this seems to be easier than creating
|
||||||
|
// a new one. This new oject contains no faces nor vertices.
|
||||||
|
Mesh *old_me;
|
||||||
|
Base *basen;
|
||||||
|
Object *ob_new;
|
||||||
|
|
||||||
|
// now create a new blender object.
|
||||||
|
// duplicating all the settings from the previous object
|
||||||
|
// to the new one.
|
||||||
|
ob_new= copy_object(base->object);
|
||||||
|
|
||||||
|
// Ok we don't want to use the actual data from the
|
||||||
|
// last object, the above function incremented the
|
||||||
|
// number of users, so decrement it here.
|
||||||
|
old_me= ob_new->data;
|
||||||
|
old_me->id.us--;
|
||||||
|
|
||||||
|
// Now create a new base to add into the linked list of
|
||||||
|
// vase objects.
|
||||||
|
|
||||||
|
basen= MEM_mallocN(sizeof(Base), "duplibase");
|
||||||
|
*basen= *base;
|
||||||
|
BLI_addhead(&scene->base, basen); /* addhead: anders oneindige lus */
|
||||||
|
basen->object= ob_new;
|
||||||
|
basen->flag &= ~SELECT;
|
||||||
|
|
||||||
|
// Initialize the mesh data associated with this object.
|
||||||
|
ob_new->data= add_mesh("Mesh");
|
||||||
|
|
||||||
|
// Finally assign the object type.
|
||||||
|
ob_new->type= OB_MESH;
|
||||||
|
|
||||||
|
return ob_new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InterpCSGFace(
|
||||||
|
DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr,
|
||||||
|
float mapmat[][4])
|
||||||
|
{
|
||||||
|
float obco[3], *co[4], *orig_co[4], w[4][4];
|
||||||
|
MFace *mface, *orig_mface;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
mface = CDDM_get_face(dm, index);
|
||||||
|
orig_mface = orig_dm->getFaceArray(orig_dm) + orig_index;
|
||||||
|
|
||||||
|
// get the vertex coordinates from the original mesh
|
||||||
|
orig_co[0] = (orig_dm->getVertArray(orig_dm) + orig_mface->v1)->co;
|
||||||
|
orig_co[1] = (orig_dm->getVertArray(orig_dm) + orig_mface->v2)->co;
|
||||||
|
orig_co[2] = (orig_dm->getVertArray(orig_dm) + orig_mface->v3)->co;
|
||||||
|
orig_co[3] = (orig_mface->v4)? (orig_dm->getVertArray(orig_dm) + orig_mface->v4)->co: NULL;
|
||||||
|
|
||||||
|
// get the vertex coordinates from the new derivedmesh
|
||||||
|
co[0] = CDDM_get_vert(dm, mface->v1)->co;
|
||||||
|
co[1] = CDDM_get_vert(dm, mface->v2)->co;
|
||||||
|
co[2] = CDDM_get_vert(dm, mface->v3)->co;
|
||||||
|
co[3] = (nr == 4)? CDDM_get_vert(dm, mface->v4)->co: NULL;
|
||||||
|
|
||||||
|
for (j = 0; j < nr; j++) {
|
||||||
|
// get coordinate into the space of the original mesh
|
||||||
|
if (mapmat)
|
||||||
|
mul_v3_m4v3(obco, mapmat, co[j]);
|
||||||
|
else
|
||||||
|
copy_v3_v3(obco, co[j]);
|
||||||
|
|
||||||
|
interp_weights_face_v3( w[j],orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomData_interp(&orig_dm->faceData, &dm->faceData, &orig_index, NULL, (float*)w, 1, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate over the CSG Output Descriptors and create a new DerivedMesh
|
||||||
|
from them */
|
||||||
|
static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
|
||||||
|
CSG_FaceIteratorDescriptor *face_it,
|
||||||
|
CSG_VertexIteratorDescriptor *vertex_it,
|
||||||
|
float parinv[][4],
|
||||||
|
float mapmat[][4],
|
||||||
|
Material **mat,
|
||||||
|
int *totmat,
|
||||||
|
DerivedMesh *dm1,
|
||||||
|
Object *ob1,
|
||||||
|
DerivedMesh *dm2,
|
||||||
|
Object *ob2)
|
||||||
|
{
|
||||||
|
DerivedMesh *result, *orig_dm;
|
||||||
|
GHash *material_hash = NULL;
|
||||||
|
Mesh *me1= (Mesh*)ob1->data;
|
||||||
|
Mesh *me2= (Mesh*)ob2->data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// create a new DerivedMesh
|
||||||
|
result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
|
||||||
|
CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
|
||||||
|
CD_DEFAULT, face_it->num_elements);
|
||||||
|
CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
|
||||||
|
CD_DEFAULT, face_it->num_elements);
|
||||||
|
|
||||||
|
// step through the vertex iterators:
|
||||||
|
for (i = 0; !vertex_it->Done(vertex_it->it); i++) {
|
||||||
|
CSG_IVertex csgvert;
|
||||||
|
MVert *mvert = CDDM_get_vert(result, i);
|
||||||
|
|
||||||
|
// retrieve a csg vertex from the boolean module
|
||||||
|
vertex_it->Fill(vertex_it->it, &csgvert);
|
||||||
|
vertex_it->Step(vertex_it->it);
|
||||||
|
|
||||||
|
// we have to map the vertex coordinates back in the coordinate frame
|
||||||
|
// of the resulting object, since it was computed in world space
|
||||||
|
mul_v3_m4v3(mvert->co, parinv, csgvert.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// a hash table to remap materials to indices
|
||||||
|
if (mat) {
|
||||||
|
material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
||||||
|
*totmat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step through the face iterators
|
||||||
|
for(i = 0; !face_it->Done(face_it->it); i++) {
|
||||||
|
Mesh *orig_me;
|
||||||
|
Object *orig_ob;
|
||||||
|
Material *orig_mat;
|
||||||
|
CSG_IFace csgface;
|
||||||
|
MFace *mface;
|
||||||
|
int orig_index, mat_nr;
|
||||||
|
|
||||||
|
// retrieve a csg face from the boolean module
|
||||||
|
face_it->Fill(face_it->it, &csgface);
|
||||||
|
face_it->Step(face_it->it);
|
||||||
|
|
||||||
|
// find the original mesh and data
|
||||||
|
orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2;
|
||||||
|
orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2;
|
||||||
|
orig_me = (orig_ob == ob1)? me1: me2;
|
||||||
|
orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1);
|
||||||
|
|
||||||
|
// copy all face layers, including mface
|
||||||
|
CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1);
|
||||||
|
|
||||||
|
// set mface
|
||||||
|
mface = CDDM_get_face(result, i);
|
||||||
|
mface->v1 = csgface.vertex_index[0];
|
||||||
|
mface->v2 = csgface.vertex_index[1];
|
||||||
|
mface->v3 = csgface.vertex_index[2];
|
||||||
|
mface->v4 = (csgface.vertex_number == 4)? csgface.vertex_index[3]: 0;
|
||||||
|
|
||||||
|
// set material, based on lookup in hash table
|
||||||
|
orig_mat= give_current_material(orig_ob, mface->mat_nr+1);
|
||||||
|
|
||||||
|
if (mat && orig_mat) {
|
||||||
|
if (!BLI_ghash_haskey(material_hash, orig_mat)) {
|
||||||
|
mat[*totmat] = orig_mat;
|
||||||
|
mat_nr = mface->mat_nr = (*totmat)++;
|
||||||
|
BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mface->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mface->mat_nr = 0;
|
||||||
|
|
||||||
|
InterpCSGFace(result, orig_dm, i, orig_index, csgface.vertex_number,
|
||||||
|
(orig_me == me2)? mapmat: NULL);
|
||||||
|
|
||||||
|
test_index_face(mface, &result->faceData, i, csgface.vertex_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material_hash)
|
||||||
|
BLI_ghash_free(material_hash, NULL, NULL);
|
||||||
|
|
||||||
|
CDDM_calc_edges(result);
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildMeshDescriptors(
|
||||||
|
struct DerivedMesh *dm,
|
||||||
|
struct Object *ob,
|
||||||
|
int face_offset,
|
||||||
|
struct CSG_FaceIteratorDescriptor * face_it,
|
||||||
|
struct CSG_VertexIteratorDescriptor * vertex_it)
|
||||||
|
{
|
||||||
|
VertexIt_Construct(vertex_it,dm, ob);
|
||||||
|
FaceIt_Construct(face_it,dm,face_offset,ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeMeshDescriptors(
|
||||||
|
struct CSG_FaceIteratorDescriptor *face_it,
|
||||||
|
struct CSG_VertexIteratorDescriptor *vertex_it)
|
||||||
|
{
|
||||||
|
VertexIt_Destruct(vertex_it);
|
||||||
|
FaceIt_Destruct(face_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
DerivedMesh *NewBooleanDerivedMesh_intern(
|
||||||
|
DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select,
|
||||||
|
int int_op_type, Material **mat, int *totmat)
|
||||||
|
{
|
||||||
|
|
||||||
|
float inv_mat[4][4];
|
||||||
|
float map_mat[4][4];
|
||||||
|
|
||||||
|
DerivedMesh *result = NULL;
|
||||||
|
|
||||||
|
if (dm == NULL || dm_select == NULL) return 0;
|
||||||
|
if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) return 0;
|
||||||
|
|
||||||
|
// we map the final object back into ob's local coordinate space. For this
|
||||||
|
// we need to compute the inverse transform from global to ob (inv_mat),
|
||||||
|
// and the transform from ob to ob_select for use in interpolation (map_mat)
|
||||||
|
invert_m4_m4(inv_mat, ob->obmat);
|
||||||
|
mul_m4_m4m4(map_mat, ob_select->obmat, inv_mat);
|
||||||
|
invert_m4_m4(inv_mat, ob_select->obmat);
|
||||||
|
|
||||||
|
{
|
||||||
|
// interface with the boolean module:
|
||||||
|
//
|
||||||
|
// the idea is, we pass the boolean module verts and faces using the
|
||||||
|
// provided descriptors. once the boolean operation is performed, we
|
||||||
|
// get back output descriptors, from which we then build a DerivedMesh
|
||||||
|
|
||||||
|
CSG_VertexIteratorDescriptor vd_1, vd_2;
|
||||||
|
CSG_FaceIteratorDescriptor fd_1, fd_2;
|
||||||
|
CSG_OperationType op_type;
|
||||||
|
CSG_BooleanOperation *bool_op;
|
||||||
|
|
||||||
|
// work out the operation they chose and pick the appropriate
|
||||||
|
// enum from the csg module.
|
||||||
|
switch (int_op_type) {
|
||||||
|
case 1 : op_type = e_csg_intersection; break;
|
||||||
|
case 2 : op_type = e_csg_union; break;
|
||||||
|
case 3 : op_type = e_csg_difference; break;
|
||||||
|
case 4 : op_type = e_csg_classify; break;
|
||||||
|
default : op_type = e_csg_intersection;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildMeshDescriptors(dm_select, ob_select, 0, &fd_1, &vd_1);
|
||||||
|
BuildMeshDescriptors(dm, ob, dm_select->getNumFaces(dm_select) , &fd_2, &vd_2);
|
||||||
|
|
||||||
|
bool_op = CSG_NewBooleanFunction();
|
||||||
|
|
||||||
|
// perform the operation
|
||||||
|
if (CSG_PerformBooleanOperation(bool_op, op_type, fd_1, vd_1, fd_2, vd_2)) {
|
||||||
|
CSG_VertexIteratorDescriptor vd_o;
|
||||||
|
CSG_FaceIteratorDescriptor fd_o;
|
||||||
|
|
||||||
|
CSG_OutputFaceDescriptor(bool_op, &fd_o);
|
||||||
|
CSG_OutputVertexDescriptor(bool_op, &vd_o);
|
||||||
|
|
||||||
|
// iterate through results of operation and insert
|
||||||
|
// into new object
|
||||||
|
result = ConvertCSGDescriptorsToDerivedMesh(
|
||||||
|
&fd_o, &vd_o, inv_mat, map_mat, mat, totmat, dm_select, ob_select, dm, ob);
|
||||||
|
|
||||||
|
// free up the memory
|
||||||
|
CSG_FreeVertexDescriptor(&vd_o);
|
||||||
|
CSG_FreeFaceDescriptor(&fd_o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Unknown internal error in boolean");
|
||||||
|
|
||||||
|
CSG_FreeBooleanOperation(bool_op);
|
||||||
|
|
||||||
|
FreeMeshDescriptors(&fd_1, &vd_1);
|
||||||
|
FreeMeshDescriptors(&fd_2, &vd_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
|
||||||
|
{
|
||||||
|
Mesh *me_new;
|
||||||
|
int a, maxmat, totmat= 0;
|
||||||
|
Object *ob_new, *ob, *ob_select;
|
||||||
|
Material **mat;
|
||||||
|
DerivedMesh *result;
|
||||||
|
DerivedMesh *dm_select;
|
||||||
|
DerivedMesh *dm;
|
||||||
|
|
||||||
|
ob= base->object;
|
||||||
|
ob_select= base_select->object;
|
||||||
|
|
||||||
|
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||||
|
dm_select = mesh_create_derived_view(scene, ob_select, 0); // no modifiers in editmode ??
|
||||||
|
|
||||||
|
maxmat= ob->totcol + ob_select->totcol;
|
||||||
|
mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat");
|
||||||
|
|
||||||
|
/* put some checks in for nice user feedback */
|
||||||
|
if (dm == NULL || dm_select == NULL) return 0;
|
||||||
|
if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select))
|
||||||
|
{
|
||||||
|
MEM_freeN(mat);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result= NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, mat, &totmat);
|
||||||
|
|
||||||
|
if (result == NULL) {
|
||||||
|
MEM_freeN(mat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a new blender mesh object - using 'base' as a template */
|
||||||
|
ob_new= AddNewBlenderMesh(scene, base_select);
|
||||||
|
me_new= ob_new->data;
|
||||||
|
|
||||||
|
DM_to_mesh(result, me_new);
|
||||||
|
result->release(result);
|
||||||
|
|
||||||
|
dm->release(dm);
|
||||||
|
dm_select->release(dm_select);
|
||||||
|
|
||||||
|
/* add materials to object */
|
||||||
|
for (a = 0; a < totmat; a++)
|
||||||
|
assign_material(ob_new, mat[a], a+1);
|
||||||
|
|
||||||
|
MEM_freeN(mat);
|
||||||
|
|
||||||
|
/* update dag */
|
||||||
|
DAG_id_flush_update(&ob_new->id, OB_RECALC_DATA);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select,
|
||||||
|
int int_op_type)
|
||||||
|
{
|
||||||
|
return NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, NULL, NULL);
|
||||||
|
}
|
||||||
50
source/blender/modifiers/intern/MOD_boolean_util.h
Normal file
50
source/blender/modifiers/intern/MOD_boolean_util.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MOD_BOOLEAN_UTILS_H
|
||||||
|
#define MOD_BOOLEAN_UTILS_H
|
||||||
|
|
||||||
|
struct Scene;
|
||||||
|
struct Object;
|
||||||
|
struct Base;
|
||||||
|
struct DerivedMesh;
|
||||||
|
|
||||||
|
/* Performs a boolean between two mesh objects, it is assumed that both objects
|
||||||
|
are in fact a mesh object. On success returns 1 and creates a new mesh object
|
||||||
|
into blender data structures. On failure returns 0 and reports an error. */
|
||||||
|
int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_select, int op);
|
||||||
|
|
||||||
|
|
||||||
|
/* Performs a boolean between two mesh objects, it is assumed that both objects
|
||||||
|
are in fact mesh object. On success returns a DerivedMesh. On failure
|
||||||
|
returns NULL and reports an error. */
|
||||||
|
|
||||||
|
struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select, int int_op_type);
|
||||||
|
|
||||||
|
#endif // MOD_BOOLEAN_UTILS
|
||||||
342
source/blender/modifiers/intern/MOD_build.c
Normal file
342
source/blender/modifiers/intern/MOD_build.c
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
BuildModifierData *bmd = (BuildModifierData*) md;
|
||||||
|
|
||||||
|
bmd->start = 1.0;
|
||||||
|
bmd->length = 100.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
BuildModifierData *bmd = (BuildModifierData*) md;
|
||||||
|
BuildModifierData *tbmd = (BuildModifierData*) target;
|
||||||
|
|
||||||
|
tbmd->start = bmd->start;
|
||||||
|
tbmd->length = bmd->length;
|
||||||
|
tbmd->randomize = bmd->randomize;
|
||||||
|
tbmd->seed = bmd->seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
||||||
|
DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
DerivedMesh *result;
|
||||||
|
BuildModifierData *bmd = (BuildModifierData*) md;
|
||||||
|
int i;
|
||||||
|
int numFaces, numEdges;
|
||||||
|
int maxVerts, maxEdges, maxFaces;
|
||||||
|
int *vertMap, *edgeMap, *faceMap;
|
||||||
|
float frac;
|
||||||
|
GHashIterator *hashIter;
|
||||||
|
/* maps vert indices in old mesh to indices in new mesh */
|
||||||
|
GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash,
|
||||||
|
BLI_ghashutil_intcmp);
|
||||||
|
/* maps edge indices in new mesh to indices in old mesh */
|
||||||
|
GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash,
|
||||||
|
BLI_ghashutil_intcmp);
|
||||||
|
|
||||||
|
maxVerts = dm->getNumVerts(dm);
|
||||||
|
vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts,
|
||||||
|
"build modifier vertMap");
|
||||||
|
for(i = 0; i < maxVerts; ++i) vertMap[i] = i;
|
||||||
|
|
||||||
|
maxEdges = dm->getNumEdges(dm);
|
||||||
|
edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges,
|
||||||
|
"build modifier edgeMap");
|
||||||
|
for(i = 0; i < maxEdges; ++i) edgeMap[i] = i;
|
||||||
|
|
||||||
|
maxFaces = dm->getNumFaces(dm);
|
||||||
|
faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces,
|
||||||
|
"build modifier faceMap");
|
||||||
|
for(i = 0; i < maxFaces; ++i) faceMap[i] = i;
|
||||||
|
|
||||||
|
if (ob) {
|
||||||
|
frac = bsystem_time(md->scene, ob, md->scene->r.cfra,
|
||||||
|
bmd->start - 1.0f) / bmd->length;
|
||||||
|
} else {
|
||||||
|
frac = md->scene->r.cfra - bmd->start / bmd->length;
|
||||||
|
}
|
||||||
|
CLAMP(frac, 0.0, 1.0);
|
||||||
|
|
||||||
|
numFaces = dm->getNumFaces(dm) * frac;
|
||||||
|
numEdges = dm->getNumEdges(dm) * frac;
|
||||||
|
|
||||||
|
/* if there's at least one face, build based on faces */
|
||||||
|
if(numFaces) {
|
||||||
|
int maxEdges;
|
||||||
|
|
||||||
|
if(bmd->randomize)
|
||||||
|
BLI_array_randomize(faceMap, sizeof(*faceMap),
|
||||||
|
maxFaces, bmd->seed);
|
||||||
|
|
||||||
|
/* get the set of all vert indices that will be in the final mesh,
|
||||||
|
* mapped to the new indices
|
||||||
|
*/
|
||||||
|
for(i = 0; i < numFaces; ++i) {
|
||||||
|
MFace mf;
|
||||||
|
dm->getFace(dm, faceMap[i], &mf);
|
||||||
|
|
||||||
|
if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)))
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1),
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
|
||||||
|
if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)))
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2),
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
|
||||||
|
if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)))
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3),
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
|
||||||
|
if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4)))
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4),
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the set of edges that will be in the new mesh (i.e. all edges
|
||||||
|
* that have both verts in the new mesh)
|
||||||
|
*/
|
||||||
|
maxEdges = dm->getNumEdges(dm);
|
||||||
|
for(i = 0; i < maxEdges; ++i) {
|
||||||
|
MEdge me;
|
||||||
|
dm->getEdge(dm, i, &me);
|
||||||
|
|
||||||
|
if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))
|
||||||
|
&& BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
|
||||||
|
BLI_ghash_insert(edgeHash,
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i));
|
||||||
|
}
|
||||||
|
} else if(numEdges) {
|
||||||
|
if(bmd->randomize)
|
||||||
|
BLI_array_randomize(edgeMap, sizeof(*edgeMap),
|
||||||
|
maxEdges, bmd->seed);
|
||||||
|
|
||||||
|
/* get the set of all vert indices that will be in the final mesh,
|
||||||
|
* mapped to the new indices
|
||||||
|
*/
|
||||||
|
for(i = 0; i < numEdges; ++i) {
|
||||||
|
MEdge me;
|
||||||
|
dm->getEdge(dm, edgeMap[i], &me);
|
||||||
|
|
||||||
|
if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)))
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1),
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
|
||||||
|
if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2),
|
||||||
|
SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the set of edges that will be in the new mesh
|
||||||
|
*/
|
||||||
|
for(i = 0; i < numEdges; ++i) {
|
||||||
|
MEdge me;
|
||||||
|
dm->getEdge(dm, edgeMap[i], &me);
|
||||||
|
|
||||||
|
BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)),
|
||||||
|
SET_INT_IN_POINTER(edgeMap[i]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int numVerts = dm->getNumVerts(dm) * frac;
|
||||||
|
|
||||||
|
if(bmd->randomize)
|
||||||
|
BLI_array_randomize(vertMap, sizeof(*vertMap),
|
||||||
|
maxVerts, bmd->seed);
|
||||||
|
|
||||||
|
/* get the set of all vert indices that will be in the final mesh,
|
||||||
|
* mapped to the new indices
|
||||||
|
*/
|
||||||
|
for(i = 0; i < numVerts; ++i)
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we know the number of verts, edges and faces, we can create
|
||||||
|
* the mesh
|
||||||
|
*/
|
||||||
|
result = CDDM_from_template(dm, BLI_ghash_size(vertHash),
|
||||||
|
BLI_ghash_size(edgeHash), numFaces);
|
||||||
|
|
||||||
|
/* copy the vertices across */
|
||||||
|
for(hashIter = BLI_ghashIterator_new(vertHash);
|
||||||
|
!BLI_ghashIterator_isDone(hashIter);
|
||||||
|
BLI_ghashIterator_step(hashIter)) {
|
||||||
|
MVert source;
|
||||||
|
MVert *dest;
|
||||||
|
int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
|
||||||
|
int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
|
||||||
|
|
||||||
|
dm->getVert(dm, oldIndex, &source);
|
||||||
|
dest = CDDM_get_vert(result, newIndex);
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
|
||||||
|
*dest = source;
|
||||||
|
}
|
||||||
|
BLI_ghashIterator_free(hashIter);
|
||||||
|
|
||||||
|
/* copy the edges across, remapping indices */
|
||||||
|
for(i = 0; i < BLI_ghash_size(edgeHash); ++i) {
|
||||||
|
MEdge source;
|
||||||
|
MEdge *dest;
|
||||||
|
int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
|
||||||
|
|
||||||
|
dm->getEdge(dm, oldIndex, &source);
|
||||||
|
dest = CDDM_get_edge(result, i);
|
||||||
|
|
||||||
|
source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
|
||||||
|
source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
|
||||||
|
|
||||||
|
DM_copy_edge_data(dm, result, oldIndex, i, 1);
|
||||||
|
*dest = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy the faces across, remapping indices */
|
||||||
|
for(i = 0; i < numFaces; ++i) {
|
||||||
|
MFace source;
|
||||||
|
MFace *dest;
|
||||||
|
int orig_v4;
|
||||||
|
|
||||||
|
dm->getFace(dm, faceMap[i], &source);
|
||||||
|
dest = CDDM_get_face(result, i);
|
||||||
|
|
||||||
|
orig_v4 = source.v4;
|
||||||
|
|
||||||
|
source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
|
||||||
|
source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
|
||||||
|
source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
|
||||||
|
if(source.v4)
|
||||||
|
source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, faceMap[i], i, 1);
|
||||||
|
*dest = source;
|
||||||
|
|
||||||
|
test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
BLI_ghash_free(vertHash, NULL, NULL);
|
||||||
|
BLI_ghash_free(edgeHash, NULL, NULL);
|
||||||
|
|
||||||
|
MEM_freeN(vertMap);
|
||||||
|
MEM_freeN(edgeMap);
|
||||||
|
MEM_freeN(faceMap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
mti = INIT_TYPE(Build);
|
||||||
|
mti->type = eModifierTypeType_Nonconstructive;
|
||||||
|
mti->flags = eModifierTypeFlag_AcceptsMesh |
|
||||||
|
eModifierTypeFlag_AcceptsCVs;
|
||||||
|
mti->initData = buildModifier_initData;
|
||||||
|
mti->copyData = buildModifier_copyData;
|
||||||
|
mti->dependsOnTime = buildModifier_dependsOnTime;
|
||||||
|
mti->applyModifier = buildModifier_applyModifier;
|
||||||
|
*/
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Build = {
|
||||||
|
/* name */ "Build",
|
||||||
|
/* structName */ "BuildModifierData",
|
||||||
|
/* structSize */ sizeof(BuildModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_AcceptsCVs,
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
667
source/blender/modifiers/intern/MOD_cast.c
Normal file
667
source/blender/modifiers/intern/MOD_cast.c
Normal file
@@ -0,0 +1,667 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
CastModifierData *cmd = (CastModifierData*) md;
|
||||||
|
|
||||||
|
cmd->fac = 0.5f;
|
||||||
|
cmd->radius = 0.0f;
|
||||||
|
cmd->size = 0.0f;
|
||||||
|
cmd->flag = MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z
|
||||||
|
| MOD_CAST_SIZE_FROM_RADIUS;
|
||||||
|
cmd->type = MOD_CAST_TYPE_SPHERE;
|
||||||
|
cmd->defgrp_name[0] = '\0';
|
||||||
|
cmd->object = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
CastModifierData *cmd = (CastModifierData*) md;
|
||||||
|
CastModifierData *tcmd = (CastModifierData*) target;
|
||||||
|
|
||||||
|
tcmd->fac = cmd->fac;
|
||||||
|
tcmd->radius = cmd->radius;
|
||||||
|
tcmd->size = cmd->size;
|
||||||
|
tcmd->flag = cmd->flag;
|
||||||
|
tcmd->type = cmd->type;
|
||||||
|
tcmd->object = cmd->object;
|
||||||
|
strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
CastModifierData *cmd = (CastModifierData*) md;
|
||||||
|
short flag;
|
||||||
|
|
||||||
|
flag = cmd->flag & (MOD_CAST_X|MOD_CAST_Y|MOD_CAST_Z);
|
||||||
|
|
||||||
|
if((cmd->fac == 0.0f) || flag == 0) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
CastModifierData *cmd = (CastModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(cmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
CastModifierData *cmd = (CastModifierData*) md;
|
||||||
|
|
||||||
|
walk (userData, ob, &cmd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
CastModifierData *cmd = (CastModifierData*) md;
|
||||||
|
|
||||||
|
if (cmd->object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, cmd->object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
|
||||||
|
"Cast Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sphere_do(
|
||||||
|
CastModifierData *cmd, Object *ob, DerivedMesh *dm,
|
||||||
|
float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
|
||||||
|
Object *ctrl_ob = NULL;
|
||||||
|
|
||||||
|
int i, defgrp_index;
|
||||||
|
int has_radius = 0;
|
||||||
|
short flag, type;
|
||||||
|
float fac, facm, len = 0.0f;
|
||||||
|
float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
float mat[4][4], imat[4][4];
|
||||||
|
|
||||||
|
fac = cmd->fac;
|
||||||
|
facm = 1.0f - fac;
|
||||||
|
|
||||||
|
flag = cmd->flag;
|
||||||
|
type = cmd->type; /* projection type: sphere or cylinder */
|
||||||
|
|
||||||
|
if (type == MOD_CAST_TYPE_CYLINDER)
|
||||||
|
flag &= ~MOD_CAST_Z;
|
||||||
|
|
||||||
|
ctrl_ob = cmd->object;
|
||||||
|
|
||||||
|
/* spherify's center is {0, 0, 0} (the ob's own center in its local
|
||||||
|
* space), by default, but if the user defined a control object,
|
||||||
|
* we use its location, transformed to ob's local space */
|
||||||
|
if (ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat);
|
||||||
|
mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat);
|
||||||
|
invert_m4_m4(imat, mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
invert_m4_m4(ob->imat, ob->obmat);
|
||||||
|
VECCOPY(center, ctrl_ob->obmat[3]);
|
||||||
|
mul_m4_v3(ob->imat, center);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we check which options the user wants */
|
||||||
|
|
||||||
|
/* 1) (flag was checked in the "if (ctrl_ob)" block above) */
|
||||||
|
/* 2) cmd->radius > 0.0f: only the vertices within this radius from
|
||||||
|
* the center of the effect should be deformed */
|
||||||
|
if (cmd->radius > FLT_EPSILON) has_radius = 1;
|
||||||
|
|
||||||
|
/* 3) if we were given a vertex group name,
|
||||||
|
* only those vertices should be affected */
|
||||||
|
defgrp_index = defgroup_name_index(ob, cmd->defgrp_name);
|
||||||
|
|
||||||
|
if ((ob->type == OB_MESH) && dm && defgrp_index >= 0)
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
if(flag & MOD_CAST_SIZE_FROM_RADIUS) {
|
||||||
|
len = cmd->radius;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len = cmd->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len <= 0) {
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
len += len_v3v3(center, vertexCos[i]);
|
||||||
|
}
|
||||||
|
len /= numVerts;
|
||||||
|
|
||||||
|
if (len == 0.0f) len = 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ready to apply the effect, one vertex at a time;
|
||||||
|
* tiny optimization: the code is separated (with parts repeated)
|
||||||
|
* in two possible cases:
|
||||||
|
* with or w/o a vgroup. With lots of if's in the code below,
|
||||||
|
* further optimizations are possible, if needed */
|
||||||
|
if (dvert) { /* with a vgroup */
|
||||||
|
float fac_orig = fac;
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
MDeformWeight *dw = NULL;
|
||||||
|
int j;
|
||||||
|
float tmp_co[3];
|
||||||
|
|
||||||
|
VECCOPY(tmp_co, vertexCos[i]);
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(mat, tmp_co);
|
||||||
|
} else {
|
||||||
|
sub_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vec, tmp_co);
|
||||||
|
|
||||||
|
if (type == MOD_CAST_TYPE_CYLINDER)
|
||||||
|
vec[2] = 0.0f;
|
||||||
|
|
||||||
|
if (has_radius) {
|
||||||
|
if (len_v3(vec) > cmd->radius) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < dvert[i].totweight; ++j) {
|
||||||
|
if(dvert[i].dw[j].def_nr == defgrp_index) {
|
||||||
|
dw = &dvert[i].dw[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dw) continue;
|
||||||
|
|
||||||
|
fac = fac_orig * dw->weight;
|
||||||
|
facm = 1.0f - fac;
|
||||||
|
|
||||||
|
normalize_v3(vec);
|
||||||
|
|
||||||
|
if (flag & MOD_CAST_X)
|
||||||
|
tmp_co[0] = fac*vec[0]*len + facm*tmp_co[0];
|
||||||
|
if (flag & MOD_CAST_Y)
|
||||||
|
tmp_co[1] = fac*vec[1]*len + facm*tmp_co[1];
|
||||||
|
if (flag & MOD_CAST_Z)
|
||||||
|
tmp_co[2] = fac*vec[2]*len + facm*tmp_co[2];
|
||||||
|
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(imat, tmp_co);
|
||||||
|
} else {
|
||||||
|
add_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vertexCos[i], tmp_co);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no vgroup */
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
float tmp_co[3];
|
||||||
|
|
||||||
|
VECCOPY(tmp_co, vertexCos[i]);
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(mat, tmp_co);
|
||||||
|
} else {
|
||||||
|
sub_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vec, tmp_co);
|
||||||
|
|
||||||
|
if (type == MOD_CAST_TYPE_CYLINDER)
|
||||||
|
vec[2] = 0.0f;
|
||||||
|
|
||||||
|
if (has_radius) {
|
||||||
|
if (len_v3(vec) > cmd->radius) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
normalize_v3(vec);
|
||||||
|
|
||||||
|
if (flag & MOD_CAST_X)
|
||||||
|
tmp_co[0] = fac*vec[0]*len + facm*tmp_co[0];
|
||||||
|
if (flag & MOD_CAST_Y)
|
||||||
|
tmp_co[1] = fac*vec[1]*len + facm*tmp_co[1];
|
||||||
|
if (flag & MOD_CAST_Z)
|
||||||
|
tmp_co[2] = fac*vec[2]*len + facm*tmp_co[2];
|
||||||
|
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(imat, tmp_co);
|
||||||
|
} else {
|
||||||
|
add_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vertexCos[i], tmp_co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cuboid_do(
|
||||||
|
CastModifierData *cmd, Object *ob, DerivedMesh *dm,
|
||||||
|
float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
Object *ctrl_ob = NULL;
|
||||||
|
|
||||||
|
int i, defgrp_index;
|
||||||
|
int has_radius = 0;
|
||||||
|
short flag;
|
||||||
|
float fac, facm;
|
||||||
|
float min[3], max[3], bb[8][3];
|
||||||
|
float center[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
float mat[4][4], imat[4][4];
|
||||||
|
|
||||||
|
fac = cmd->fac;
|
||||||
|
facm = 1.0f - fac;
|
||||||
|
|
||||||
|
flag = cmd->flag;
|
||||||
|
|
||||||
|
ctrl_ob = cmd->object;
|
||||||
|
|
||||||
|
/* now we check which options the user wants */
|
||||||
|
|
||||||
|
/* 1) (flag was checked in the "if (ctrl_ob)" block above) */
|
||||||
|
/* 2) cmd->radius > 0.0f: only the vertices within this radius from
|
||||||
|
* the center of the effect should be deformed */
|
||||||
|
if (cmd->radius > FLT_EPSILON) has_radius = 1;
|
||||||
|
|
||||||
|
/* 3) if we were given a vertex group name,
|
||||||
|
* only those vertices should be affected */
|
||||||
|
defgrp_index = defgroup_name_index(ob, cmd->defgrp_name);
|
||||||
|
|
||||||
|
if ((ob->type == OB_MESH) && dm && defgrp_index >= 0)
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
if (ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat);
|
||||||
|
mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat);
|
||||||
|
invert_m4_m4(imat, mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
invert_m4_m4(ob->imat, ob->obmat);
|
||||||
|
VECCOPY(center, ctrl_ob->obmat[3]);
|
||||||
|
mul_m4_v3(ob->imat, center);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((flag & MOD_CAST_SIZE_FROM_RADIUS) && has_radius) {
|
||||||
|
for(i = 0; i < 3; i++) {
|
||||||
|
min[i] = -cmd->radius;
|
||||||
|
max[i] = cmd->radius;
|
||||||
|
}
|
||||||
|
} else if(!(flag & MOD_CAST_SIZE_FROM_RADIUS) && cmd->size > 0) {
|
||||||
|
for(i = 0; i < 3; i++) {
|
||||||
|
min[i] = -cmd->size;
|
||||||
|
max[i] = cmd->size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* get bound box */
|
||||||
|
/* We can't use the object's bound box because other modifiers
|
||||||
|
* may have changed the vertex data. */
|
||||||
|
INIT_MINMAX(min, max);
|
||||||
|
|
||||||
|
/* Cast's center is the ob's own center in its local space,
|
||||||
|
* by default, but if the user defined a control object, we use
|
||||||
|
* its location, transformed to ob's local space. */
|
||||||
|
if (ctrl_ob) {
|
||||||
|
float vec[3];
|
||||||
|
|
||||||
|
/* let the center of the ctrl_ob be part of the bound box: */
|
||||||
|
DO_MINMAX(center, min, max);
|
||||||
|
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
sub_v3_v3v3(vec, vertexCos[i], center);
|
||||||
|
DO_MINMAX(vec, min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
DO_MINMAX(vertexCos[i], min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we want a symmetric bound box around the origin */
|
||||||
|
if (fabs(min[0]) > fabs(max[0])) max[0] = fabs(min[0]);
|
||||||
|
if (fabs(min[1]) > fabs(max[1])) max[1] = fabs(min[1]);
|
||||||
|
if (fabs(min[2]) > fabs(max[2])) max[2] = fabs(min[2]);
|
||||||
|
min[0] = -max[0];
|
||||||
|
min[1] = -max[1];
|
||||||
|
min[2] = -max[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* building our custom bounding box */
|
||||||
|
bb[0][0] = bb[2][0] = bb[4][0] = bb[6][0] = min[0];
|
||||||
|
bb[1][0] = bb[3][0] = bb[5][0] = bb[7][0] = max[0];
|
||||||
|
bb[0][1] = bb[1][1] = bb[4][1] = bb[5][1] = min[1];
|
||||||
|
bb[2][1] = bb[3][1] = bb[6][1] = bb[7][1] = max[1];
|
||||||
|
bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
|
||||||
|
bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
|
||||||
|
|
||||||
|
/* ready to apply the effect, one vertex at a time;
|
||||||
|
* tiny optimization: the code is separated (with parts repeated)
|
||||||
|
* in two possible cases:
|
||||||
|
* with or w/o a vgroup. With lots of if's in the code below,
|
||||||
|
* further optimizations are possible, if needed */
|
||||||
|
if (dvert) { /* with a vgroup */
|
||||||
|
float fac_orig = fac;
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
MDeformWeight *dw = NULL;
|
||||||
|
int j, octant, coord;
|
||||||
|
float d[3], dmax, apex[3], fbb;
|
||||||
|
float tmp_co[3];
|
||||||
|
|
||||||
|
VECCOPY(tmp_co, vertexCos[i]);
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(mat, tmp_co);
|
||||||
|
} else {
|
||||||
|
sub_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_radius) {
|
||||||
|
if (fabs(tmp_co[0]) > cmd->radius ||
|
||||||
|
fabs(tmp_co[1]) > cmd->radius ||
|
||||||
|
fabs(tmp_co[2]) > cmd->radius) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < dvert[i].totweight; ++j) {
|
||||||
|
if(dvert[i].dw[j].def_nr == defgrp_index) {
|
||||||
|
dw = &dvert[i].dw[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dw) continue;
|
||||||
|
|
||||||
|
fac = fac_orig * dw->weight;
|
||||||
|
facm = 1.0f - fac;
|
||||||
|
|
||||||
|
/* The algo used to project the vertices to their
|
||||||
|
* bounding box (bb) is pretty simple:
|
||||||
|
* for each vertex v:
|
||||||
|
* 1) find in which octant v is in;
|
||||||
|
* 2) find which outer "wall" of that octant is closer to v;
|
||||||
|
* 3) calculate factor (var fbb) to project v to that wall;
|
||||||
|
* 4) project. */
|
||||||
|
|
||||||
|
/* find in which octant this vertex is in */
|
||||||
|
octant = 0;
|
||||||
|
if (tmp_co[0] > 0.0f) octant += 1;
|
||||||
|
if (tmp_co[1] > 0.0f) octant += 2;
|
||||||
|
if (tmp_co[2] > 0.0f) octant += 4;
|
||||||
|
|
||||||
|
/* apex is the bb's vertex at the chosen octant */
|
||||||
|
copy_v3_v3(apex, bb[octant]);
|
||||||
|
|
||||||
|
/* find which bb plane is closest to this vertex ... */
|
||||||
|
d[0] = tmp_co[0] / apex[0];
|
||||||
|
d[1] = tmp_co[1] / apex[1];
|
||||||
|
d[2] = tmp_co[2] / apex[2];
|
||||||
|
|
||||||
|
/* ... (the closest has the higher (closer to 1) d value) */
|
||||||
|
dmax = d[0];
|
||||||
|
coord = 0;
|
||||||
|
if (d[1] > dmax) {
|
||||||
|
dmax = d[1];
|
||||||
|
coord = 1;
|
||||||
|
}
|
||||||
|
if (d[2] > dmax) {
|
||||||
|
/* dmax = d[2]; */ /* commented, we don't need it */
|
||||||
|
coord = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ok, now we know which coordinate of the vertex to use */
|
||||||
|
|
||||||
|
if (fabs(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* finally, this is the factor we wanted, to project the vertex
|
||||||
|
* to its bounding box (bb) */
|
||||||
|
fbb = apex[coord] / tmp_co[coord];
|
||||||
|
|
||||||
|
/* calculate the new vertex position */
|
||||||
|
if (flag & MOD_CAST_X)
|
||||||
|
tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
|
||||||
|
if (flag & MOD_CAST_Y)
|
||||||
|
tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
|
||||||
|
if (flag & MOD_CAST_Z)
|
||||||
|
tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
|
||||||
|
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(imat, tmp_co);
|
||||||
|
} else {
|
||||||
|
add_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vertexCos[i], tmp_co);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no vgroup (check previous case for comments about the code) */
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
int octant, coord;
|
||||||
|
float d[3], dmax, fbb, apex[3];
|
||||||
|
float tmp_co[3];
|
||||||
|
|
||||||
|
VECCOPY(tmp_co, vertexCos[i]);
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(mat, tmp_co);
|
||||||
|
} else {
|
||||||
|
sub_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_radius) {
|
||||||
|
if (fabs(tmp_co[0]) > cmd->radius ||
|
||||||
|
fabs(tmp_co[1]) > cmd->radius ||
|
||||||
|
fabs(tmp_co[2]) > cmd->radius) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
octant = 0;
|
||||||
|
if (tmp_co[0] > 0.0f) octant += 1;
|
||||||
|
if (tmp_co[1] > 0.0f) octant += 2;
|
||||||
|
if (tmp_co[2] > 0.0f) octant += 4;
|
||||||
|
|
||||||
|
copy_v3_v3(apex, bb[octant]);
|
||||||
|
|
||||||
|
d[0] = tmp_co[0] / apex[0];
|
||||||
|
d[1] = tmp_co[1] / apex[1];
|
||||||
|
d[2] = tmp_co[2] / apex[2];
|
||||||
|
|
||||||
|
dmax = d[0];
|
||||||
|
coord = 0;
|
||||||
|
if (d[1] > dmax) {
|
||||||
|
dmax = d[1];
|
||||||
|
coord = 1;
|
||||||
|
}
|
||||||
|
if (d[2] > dmax) {
|
||||||
|
/* dmax = d[2]; */ /* commented, we don't need it */
|
||||||
|
coord = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(tmp_co[coord]) < FLT_EPSILON)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fbb = apex[coord] / tmp_co[coord];
|
||||||
|
|
||||||
|
if (flag & MOD_CAST_X)
|
||||||
|
tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
|
||||||
|
if (flag & MOD_CAST_Y)
|
||||||
|
tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
|
||||||
|
if (flag & MOD_CAST_Z)
|
||||||
|
tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
|
||||||
|
|
||||||
|
if(ctrl_ob) {
|
||||||
|
if(flag & MOD_CAST_USE_OB_TRANSFORM) {
|
||||||
|
mul_m4_v3(imat, tmp_co);
|
||||||
|
} else {
|
||||||
|
add_v3_v3v3(tmp_co, tmp_co, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vertexCos[i], tmp_co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = NULL;
|
||||||
|
CastModifierData *cmd = (CastModifierData *)md;
|
||||||
|
|
||||||
|
dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
|
||||||
|
|
||||||
|
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
|
||||||
|
cuboid_do(cmd, ob, dm, vertexCos, numVerts);
|
||||||
|
} else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
|
||||||
|
sphere_do(cmd, ob, dm, vertexCos, numVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = get_dm(md->scene, ob, editData, derivedData, NULL, 0);
|
||||||
|
CastModifierData *cmd = (CastModifierData *)md;
|
||||||
|
|
||||||
|
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
|
||||||
|
cuboid_do(cmd, ob, dm, vertexCos, numVerts);
|
||||||
|
} else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
|
||||||
|
sphere_do(cmd, ob, dm, vertexCos, numVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Cast = {
|
||||||
|
/* name */ "Cast",
|
||||||
|
/* structName */ "CastModifierData",
|
||||||
|
/* structSize */ sizeof(CastModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
244
source/blender/modifiers/intern/MOD_cloth.c
Normal file
244
source/blender/modifiers/intern/MOD_cloth.c
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||||
|
|
||||||
|
clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
|
||||||
|
clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
|
||||||
|
clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
|
||||||
|
|
||||||
|
/* check for alloc failing */
|
||||||
|
if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cloth_init (clmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
||||||
|
DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||||
|
DerivedMesh *result=NULL;
|
||||||
|
|
||||||
|
/* check for alloc failing */
|
||||||
|
if(!clmd->sim_parms || !clmd->coll_parms)
|
||||||
|
{
|
||||||
|
initData(md);
|
||||||
|
|
||||||
|
if(!clmd->sim_parms || !clmd->coll_parms)
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = clothModifier_do(clmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||||
|
|
||||||
|
Base *base;
|
||||||
|
|
||||||
|
if(clmd)
|
||||||
|
{
|
||||||
|
for(base = scene->base.first; base; base= base->next)
|
||||||
|
{
|
||||||
|
Object *ob1= base->object;
|
||||||
|
if(ob1 != ob)
|
||||||
|
{
|
||||||
|
CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
|
||||||
|
if(coll_clmd)
|
||||||
|
{
|
||||||
|
DagNode *curNode = dag_get_node(forest, ob1);
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Cloth Collision");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
ClothModifierData *clmd = (ClothModifierData*)md;
|
||||||
|
|
||||||
|
if(cloth_uses_vgroup(clmd))
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
if(clmd->sim_parms->shapekey_rest != 0)
|
||||||
|
dataMask |= (1 << CD_CLOTH_ORCO);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||||
|
ClothModifierData *tclmd = (ClothModifierData*) target;
|
||||||
|
|
||||||
|
if(tclmd->sim_parms)
|
||||||
|
MEM_freeN(tclmd->sim_parms);
|
||||||
|
if(tclmd->coll_parms)
|
||||||
|
MEM_freeN(tclmd->coll_parms);
|
||||||
|
|
||||||
|
BKE_ptcache_free_list(&tclmd->ptcaches);
|
||||||
|
tclmd->point_cache = NULL;
|
||||||
|
|
||||||
|
tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
|
||||||
|
if(clmd->sim_parms->effector_weights)
|
||||||
|
tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
|
||||||
|
tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
|
||||||
|
tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
|
||||||
|
tclmd->clothObject = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||||
|
|
||||||
|
if (clmd)
|
||||||
|
{
|
||||||
|
if(G.rt > 0)
|
||||||
|
printf("clothModifier_freeData\n");
|
||||||
|
|
||||||
|
cloth_free_modifier_extern (clmd);
|
||||||
|
|
||||||
|
if(clmd->sim_parms) {
|
||||||
|
if(clmd->sim_parms->effector_weights)
|
||||||
|
MEM_freeN(clmd->sim_parms->effector_weights);
|
||||||
|
MEM_freeN(clmd->sim_parms);
|
||||||
|
}
|
||||||
|
if(clmd->coll_parms)
|
||||||
|
MEM_freeN(clmd->coll_parms);
|
||||||
|
|
||||||
|
BKE_ptcache_free_list(&clmd->ptcaches);
|
||||||
|
clmd->point_cache = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Cloth = {
|
||||||
|
/* name */ "Cloth",
|
||||||
|
/* structName */ "ClothModifierData",
|
||||||
|
/* structSize */ sizeof(ClothModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh |
|
||||||
|
eModifierTypeFlag_UsesPointCache |
|
||||||
|
eModifierTypeFlag_Single,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
292
source/blender/modifiers/intern/MOD_collision.c
Normal file
292
source/blender/modifiers/intern/MOD_collision.c
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
CollisionModifierData *collmd = (CollisionModifierData*) md;
|
||||||
|
|
||||||
|
collmd->x = NULL;
|
||||||
|
collmd->xnew = NULL;
|
||||||
|
collmd->current_x = NULL;
|
||||||
|
collmd->current_xnew = NULL;
|
||||||
|
collmd->current_v = NULL;
|
||||||
|
collmd->time = -1000;
|
||||||
|
collmd->numverts = 0;
|
||||||
|
collmd->bvhtree = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
CollisionModifierData *collmd = (CollisionModifierData*) md;
|
||||||
|
|
||||||
|
if (collmd)
|
||||||
|
{
|
||||||
|
if(collmd->bvhtree)
|
||||||
|
BLI_bvhtree_free(collmd->bvhtree);
|
||||||
|
if(collmd->x)
|
||||||
|
MEM_freeN(collmd->x);
|
||||||
|
if(collmd->xnew)
|
||||||
|
MEM_freeN(collmd->xnew);
|
||||||
|
if(collmd->current_x)
|
||||||
|
MEM_freeN(collmd->current_x);
|
||||||
|
if(collmd->current_xnew)
|
||||||
|
MEM_freeN(collmd->current_xnew);
|
||||||
|
if(collmd->current_v)
|
||||||
|
MEM_freeN(collmd->current_v);
|
||||||
|
if(collmd->mfaces)
|
||||||
|
MEM_freeN(collmd->mfaces);
|
||||||
|
|
||||||
|
collmd->x = NULL;
|
||||||
|
collmd->xnew = NULL;
|
||||||
|
collmd->current_x = NULL;
|
||||||
|
collmd->current_xnew = NULL;
|
||||||
|
collmd->current_v = NULL;
|
||||||
|
collmd->time = -1000;
|
||||||
|
collmd->numverts = 0;
|
||||||
|
collmd->bvhtree = NULL;
|
||||||
|
collmd->mfaces = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
CollisionModifierData *collmd = (CollisionModifierData*) md;
|
||||||
|
DerivedMesh *dm = NULL;
|
||||||
|
float current_time = 0;
|
||||||
|
unsigned int numverts = 0, i = 0;
|
||||||
|
MVert *tempVert = NULL;
|
||||||
|
|
||||||
|
/* if possible use/create DerivedMesh */
|
||||||
|
if(derivedData) dm = CDDM_copy(derivedData);
|
||||||
|
else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
|
||||||
|
|
||||||
|
if(!ob->pd)
|
||||||
|
{
|
||||||
|
printf("CollisionModifier deformVerts: Should not happen!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dm)
|
||||||
|
{
|
||||||
|
CDDM_apply_vert_coords(dm, vertexCos);
|
||||||
|
CDDM_calc_normals(dm);
|
||||||
|
|
||||||
|
current_time = bsystem_time (md->scene, ob, ( float ) md->scene->r.cfra, 0.0 );
|
||||||
|
|
||||||
|
if(G.rt > 0)
|
||||||
|
printf("current_time %f, collmd->time %f\n", current_time, collmd->time);
|
||||||
|
|
||||||
|
numverts = dm->getNumVerts ( dm );
|
||||||
|
|
||||||
|
if((current_time > collmd->time)|| (BKE_ptcache_get_continue_physics()))
|
||||||
|
{
|
||||||
|
// check if mesh has changed
|
||||||
|
if(collmd->x && (numverts != collmd->numverts))
|
||||||
|
freeData((ModifierData *)collmd);
|
||||||
|
|
||||||
|
if(collmd->time == -1000) // first time
|
||||||
|
{
|
||||||
|
collmd->x = dm->dupVertArray(dm); // frame start position
|
||||||
|
|
||||||
|
for ( i = 0; i < numverts; i++ )
|
||||||
|
{
|
||||||
|
// we save global positions
|
||||||
|
mul_m4_v3( ob->obmat, collmd->x[i].co );
|
||||||
|
}
|
||||||
|
|
||||||
|
collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
|
||||||
|
collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
|
||||||
|
collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
|
||||||
|
collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
|
||||||
|
|
||||||
|
collmd->numverts = numverts;
|
||||||
|
|
||||||
|
collmd->mfaces = dm->dupFaceArray(dm);
|
||||||
|
collmd->numfaces = dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
// create bounding box hierarchy
|
||||||
|
collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
|
||||||
|
|
||||||
|
collmd->time = current_time;
|
||||||
|
}
|
||||||
|
else if(numverts == collmd->numverts)
|
||||||
|
{
|
||||||
|
// put positions to old positions
|
||||||
|
tempVert = collmd->x;
|
||||||
|
collmd->x = collmd->xnew;
|
||||||
|
collmd->xnew = tempVert;
|
||||||
|
|
||||||
|
memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
|
||||||
|
|
||||||
|
for ( i = 0; i < numverts; i++ )
|
||||||
|
{
|
||||||
|
// we save global positions
|
||||||
|
mul_m4_v3( ob->obmat, collmd->xnew[i].co );
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert));
|
||||||
|
memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert));
|
||||||
|
|
||||||
|
/* check if GUI setting has changed for bvh */
|
||||||
|
if(collmd->bvhtree)
|
||||||
|
{
|
||||||
|
if(ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree))
|
||||||
|
{
|
||||||
|
BLI_bvhtree_free(collmd->bvhtree);
|
||||||
|
collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* happens on file load (ONLY when i decomment changes in readfile.c) */
|
||||||
|
if(!collmd->bvhtree)
|
||||||
|
{
|
||||||
|
collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// recalc static bounding boxes
|
||||||
|
bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
collmd->time = current_time;
|
||||||
|
}
|
||||||
|
else if(numverts != collmd->numverts)
|
||||||
|
{
|
||||||
|
freeData((ModifierData *)collmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(current_time < collmd->time)
|
||||||
|
{
|
||||||
|
freeData((ModifierData *)collmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(numverts != collmd->numverts)
|
||||||
|
{
|
||||||
|
freeData((ModifierData *)collmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dm)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Collision = {
|
||||||
|
/* name */ "Collision",
|
||||||
|
/* structName */ "CollisionModifierData",
|
||||||
|
/* structSize */ sizeof(CollisionModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_Single,
|
||||||
|
|
||||||
|
/* copyData */ 0,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
195
source/blender/modifiers/intern/MOD_curve.c
Normal file
195
source/blender/modifiers/intern/MOD_curve.c
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData*) md;
|
||||||
|
|
||||||
|
cmd->defaxis = MOD_CURVE_POSX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData*) md;
|
||||||
|
CurveModifierData *tcmd = (CurveModifierData*) target;
|
||||||
|
|
||||||
|
tcmd->defaxis = cmd->defaxis;
|
||||||
|
tcmd->object = cmd->object;
|
||||||
|
strncpy(tcmd->name, cmd->name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(cmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int userRenderParams)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData*) md;
|
||||||
|
|
||||||
|
return !cmd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &cmd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData*) md;
|
||||||
|
|
||||||
|
if (cmd->object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, cmd->object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
CurveModifierData *cmd = (CurveModifierData*) md;
|
||||||
|
|
||||||
|
curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts,
|
||||||
|
cmd->name, cmd->defaxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
|
||||||
|
deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
|
||||||
|
|
||||||
|
if(!derivedData) dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Curve = {
|
||||||
|
/* name */ "Curve",
|
||||||
|
/* structName */ "CurveModifierData",
|
||||||
|
/* structSize */ sizeof(CurveModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
243
source/blender/modifiers/intern/MOD_decimate.c
Normal file
243
source/blender/modifiers/intern/MOD_decimate.c
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
DecimateModifierData *dmd = (DecimateModifierData*) md;
|
||||||
|
|
||||||
|
dmd->percent = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
DecimateModifierData *dmd = (DecimateModifierData*) md;
|
||||||
|
DecimateModifierData *tdmd = (DecimateModifierData*) target;
|
||||||
|
|
||||||
|
tdmd->percent = dmd->percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DecimateModifierData *dmd = (DecimateModifierData*) md;
|
||||||
|
DerivedMesh *dm = derivedData, *result = NULL;
|
||||||
|
MVert *mvert;
|
||||||
|
MFace *mface;
|
||||||
|
LOD_Decimation_Info lod;
|
||||||
|
int totvert, totface;
|
||||||
|
int a, numTris;
|
||||||
|
|
||||||
|
mvert = dm->getVertArray(dm);
|
||||||
|
mface = dm->getFaceArray(dm);
|
||||||
|
totvert = dm->getNumVerts(dm);
|
||||||
|
totface = dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
numTris = 0;
|
||||||
|
for (a=0; a<totface; a++) {
|
||||||
|
MFace *mf = &mface[a];
|
||||||
|
numTris++;
|
||||||
|
if (mf->v4) numTris++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(numTris<3) {
|
||||||
|
modifier_setError(md,
|
||||||
|
"Modifier requires more than 3 input faces (triangles).");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
|
||||||
|
lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
|
||||||
|
lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
|
||||||
|
lod.vertex_num= totvert;
|
||||||
|
lod.face_num= numTris;
|
||||||
|
|
||||||
|
for(a=0; a<totvert; a++) {
|
||||||
|
MVert *mv = &mvert[a];
|
||||||
|
float *vbCo = &lod.vertex_buffer[a*3];
|
||||||
|
float *vbNo = &lod.vertex_normal_buffer[a*3];
|
||||||
|
|
||||||
|
VECCOPY(vbCo, mv->co);
|
||||||
|
|
||||||
|
vbNo[0] = mv->no[0]/32767.0f;
|
||||||
|
vbNo[1] = mv->no[1]/32767.0f;
|
||||||
|
vbNo[2] = mv->no[2]/32767.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
numTris = 0;
|
||||||
|
for(a=0; a<totface; a++) {
|
||||||
|
MFace *mf = &mface[a];
|
||||||
|
int *tri = &lod.triangle_index_buffer[3*numTris++];
|
||||||
|
tri[0]= mf->v1;
|
||||||
|
tri[1]= mf->v2;
|
||||||
|
tri[2]= mf->v3;
|
||||||
|
|
||||||
|
if(mf->v4) {
|
||||||
|
tri = &lod.triangle_index_buffer[3*numTris++];
|
||||||
|
tri[0]= mf->v1;
|
||||||
|
tri[1]= mf->v3;
|
||||||
|
tri[2]= mf->v4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dmd->faceCount = 0;
|
||||||
|
if(LOD_LoadMesh(&lod) ) {
|
||||||
|
if( LOD_PreprocessMesh(&lod) ) {
|
||||||
|
/* we assume the decim_faces tells how much to reduce */
|
||||||
|
|
||||||
|
while(lod.face_num > numTris*dmd->percent) {
|
||||||
|
if( LOD_CollapseEdge(&lod)==0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lod.vertex_num>2) {
|
||||||
|
result = CDDM_new(lod.vertex_num, 0, lod.face_num);
|
||||||
|
dmd->faceCount = lod.face_num;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = CDDM_new(lod.vertex_num, 0, 0);
|
||||||
|
|
||||||
|
mvert = CDDM_get_verts(result);
|
||||||
|
for(a=0; a<lod.vertex_num; a++) {
|
||||||
|
MVert *mv = &mvert[a];
|
||||||
|
float *vbCo = &lod.vertex_buffer[a*3];
|
||||||
|
|
||||||
|
VECCOPY(mv->co, vbCo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lod.vertex_num>2) {
|
||||||
|
mface = CDDM_get_faces(result);
|
||||||
|
for(a=0; a<lod.face_num; a++) {
|
||||||
|
MFace *mf = &mface[a];
|
||||||
|
int *tri = &lod.triangle_index_buffer[a*3];
|
||||||
|
mf->v1 = tri[0];
|
||||||
|
mf->v2 = tri[1];
|
||||||
|
mf->v3 = tri[2];
|
||||||
|
test_index_face(mf, NULL, 0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CDDM_calc_edges(result);
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
modifier_setError(md, "Out of memory.");
|
||||||
|
|
||||||
|
LOD_FreeDecimationData(&lod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
modifier_setError(md, "Non-manifold mesh as input.");
|
||||||
|
|
||||||
|
MEM_freeN(lod.vertex_buffer);
|
||||||
|
MEM_freeN(lod.vertex_normal_buffer);
|
||||||
|
MEM_freeN(lod.triangle_index_buffer);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Decimate = {
|
||||||
|
/* name */ "Decimate",
|
||||||
|
/* structName */ "DecimateModifierData",
|
||||||
|
/* structSize */ sizeof(DecimateModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh,
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
396
source/blender/modifiers/intern/MOD_displace.c
Normal file
396
source/blender/modifiers/intern/MOD_displace.c
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Displace */
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
|
||||||
|
|
||||||
|
dmd->texture = NULL;
|
||||||
|
dmd->strength = 1;
|
||||||
|
dmd->direction = MOD_DISP_DIR_NOR;
|
||||||
|
dmd->midlevel = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
|
||||||
|
DisplaceModifierData *tdmd = (DisplaceModifierData*) target;
|
||||||
|
|
||||||
|
tdmd->texture = dmd->texture;
|
||||||
|
tdmd->strength = dmd->strength;
|
||||||
|
tdmd->direction = dmd->direction;
|
||||||
|
strncpy(tdmd->defgrp_name, dmd->defgrp_name, 32);
|
||||||
|
tdmd->midlevel = dmd->midlevel;
|
||||||
|
tdmd->texmapping = dmd->texmapping;
|
||||||
|
tdmd->map_object = dmd->map_object;
|
||||||
|
strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(dmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
/* ask for UV coordinates if we need them */
|
||||||
|
if(dmd->texmapping == MOD_DISP_MAP_UV) dataMask |= (1 << CD_MTFACE);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData *)md;
|
||||||
|
|
||||||
|
if(dmd->texture)
|
||||||
|
{
|
||||||
|
return BKE_texture_dependsOnTime(dmd->texture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(ModifierData *md, Object *ob,
|
||||||
|
ObjectWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &dmd->map_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachIDLink(ModifierData *md, Object *ob,
|
||||||
|
IDWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, (ID **)&dmd->texture);
|
||||||
|
|
||||||
|
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
|
||||||
|
|
||||||
|
return !dmd->texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
|
||||||
|
|
||||||
|
if(dmd->map_object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, dmd->map_object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
|
||||||
|
DerivedMesh *dm,
|
||||||
|
float (*co)[3], float (*texco)[3],
|
||||||
|
int numVerts)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int texmapping = dmd->texmapping;
|
||||||
|
float mapob_imat[4][4];
|
||||||
|
|
||||||
|
if(texmapping == MOD_DISP_MAP_OBJECT) {
|
||||||
|
if(dmd->map_object)
|
||||||
|
invert_m4_m4(mapob_imat, dmd->map_object->obmat);
|
||||||
|
else /* if there is no map object, default to local */
|
||||||
|
texmapping = MOD_DISP_MAP_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UVs need special handling, since they come from faces */
|
||||||
|
if(texmapping == MOD_DISP_MAP_UV) {
|
||||||
|
if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
|
||||||
|
MFace *mface = dm->getFaceArray(dm);
|
||||||
|
MFace *mf;
|
||||||
|
char *done = MEM_callocN(sizeof(*done) * numVerts,
|
||||||
|
"get_texture_coords done");
|
||||||
|
int numFaces = dm->getNumFaces(dm);
|
||||||
|
char uvname[32];
|
||||||
|
MTFace *tf;
|
||||||
|
|
||||||
|
validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
|
||||||
|
tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
|
||||||
|
|
||||||
|
/* verts are given the UV from the first face that uses them */
|
||||||
|
for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
|
||||||
|
if(!done[mf->v1]) {
|
||||||
|
texco[mf->v1][0] = tf->uv[0][0];
|
||||||
|
texco[mf->v1][1] = tf->uv[0][1];
|
||||||
|
texco[mf->v1][2] = 0;
|
||||||
|
done[mf->v1] = 1;
|
||||||
|
}
|
||||||
|
if(!done[mf->v2]) {
|
||||||
|
texco[mf->v2][0] = tf->uv[1][0];
|
||||||
|
texco[mf->v2][1] = tf->uv[1][1];
|
||||||
|
texco[mf->v2][2] = 0;
|
||||||
|
done[mf->v2] = 1;
|
||||||
|
}
|
||||||
|
if(!done[mf->v3]) {
|
||||||
|
texco[mf->v3][0] = tf->uv[2][0];
|
||||||
|
texco[mf->v3][1] = tf->uv[2][1];
|
||||||
|
texco[mf->v3][2] = 0;
|
||||||
|
done[mf->v3] = 1;
|
||||||
|
}
|
||||||
|
if(!done[mf->v4]) {
|
||||||
|
texco[mf->v4][0] = tf->uv[3][0];
|
||||||
|
texco[mf->v4][1] = tf->uv[3][1];
|
||||||
|
texco[mf->v4][2] = 0;
|
||||||
|
done[mf->v4] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remap UVs from [0, 1] to [-1, 1] */
|
||||||
|
for(i = 0; i < numVerts; ++i) {
|
||||||
|
texco[i][0] = texco[i][0] * 2 - 1;
|
||||||
|
texco[i][1] = texco[i][1] * 2 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(done);
|
||||||
|
return;
|
||||||
|
} else /* if there are no UVs, default to local */
|
||||||
|
texmapping = MOD_DISP_MAP_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < numVerts; ++i, ++co, ++texco) {
|
||||||
|
switch(texmapping) {
|
||||||
|
case MOD_DISP_MAP_LOCAL:
|
||||||
|
VECCOPY(*texco, *co);
|
||||||
|
break;
|
||||||
|
case MOD_DISP_MAP_GLOBAL:
|
||||||
|
VECCOPY(*texco, *co);
|
||||||
|
mul_m4_v3(ob->obmat, *texco);
|
||||||
|
break;
|
||||||
|
case MOD_DISP_MAP_OBJECT:
|
||||||
|
VECCOPY(*texco, *co);
|
||||||
|
mul_m4_v3(ob->obmat, *texco);
|
||||||
|
mul_m4_v3(mapob_imat, *texco);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dm must be a CDDerivedMesh */
|
||||||
|
static void displaceModifier_do(
|
||||||
|
DisplaceModifierData *dmd, Object *ob,
|
||||||
|
DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
MVert *mvert;
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
int defgrp_index;
|
||||||
|
float (*tex_co)[3];
|
||||||
|
|
||||||
|
if(!dmd->texture) return;
|
||||||
|
|
||||||
|
defgrp_index = defgroup_name_index(ob, dmd->defgrp_name);
|
||||||
|
|
||||||
|
mvert = CDDM_get_verts(dm);
|
||||||
|
if(defgrp_index >= 0)
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
tex_co = MEM_callocN(sizeof(*tex_co) * numVerts,
|
||||||
|
"displaceModifier_do tex_co");
|
||||||
|
get_texture_coords(dmd, ob, dm, vertexCos, tex_co, numVerts);
|
||||||
|
|
||||||
|
for(i = 0; i < numVerts; ++i) {
|
||||||
|
TexResult texres;
|
||||||
|
float delta = 0, strength = dmd->strength;
|
||||||
|
MDeformWeight *def_weight = NULL;
|
||||||
|
|
||||||
|
if(dvert) {
|
||||||
|
int j;
|
||||||
|
for(j = 0; j < dvert[i].totweight; ++j) {
|
||||||
|
if(dvert[i].dw[j].def_nr == defgrp_index) {
|
||||||
|
def_weight = &dvert[i].dw[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!def_weight) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
texres.nor = NULL;
|
||||||
|
get_texture_value(dmd->texture, tex_co[i], &texres);
|
||||||
|
|
||||||
|
delta = texres.tin - dmd->midlevel;
|
||||||
|
|
||||||
|
if(def_weight) strength *= def_weight->weight;
|
||||||
|
|
||||||
|
delta *= strength;
|
||||||
|
|
||||||
|
switch(dmd->direction) {
|
||||||
|
case MOD_DISP_DIR_X:
|
||||||
|
vertexCos[i][0] += delta;
|
||||||
|
break;
|
||||||
|
case MOD_DISP_DIR_Y:
|
||||||
|
vertexCos[i][1] += delta;
|
||||||
|
break;
|
||||||
|
case MOD_DISP_DIR_Z:
|
||||||
|
vertexCos[i][2] += delta;
|
||||||
|
break;
|
||||||
|
case MOD_DISP_DIR_RGB_XYZ:
|
||||||
|
vertexCos[i][0] += (texres.tr - dmd->midlevel) * strength;
|
||||||
|
vertexCos[i][1] += (texres.tg - dmd->midlevel) * strength;
|
||||||
|
vertexCos[i][2] += (texres.tb - dmd->midlevel) * strength;
|
||||||
|
break;
|
||||||
|
case MOD_DISP_DIR_NOR:
|
||||||
|
vertexCos[i][0] += delta * mvert[i].no[0] / 32767.0f;
|
||||||
|
vertexCos[i][1] += delta * mvert[i].no[1] / 32767.0f;
|
||||||
|
vertexCos[i][2] += delta * mvert[i].no[2] / 32767.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(tex_co);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos);
|
||||||
|
|
||||||
|
displaceModifier_do((DisplaceModifierData *)md, ob, dm,
|
||||||
|
vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= get_cddm(md->scene, ob, editData, derivedData, vertexCos);
|
||||||
|
|
||||||
|
displaceModifier_do((DisplaceModifierData *)md, ob, dm,
|
||||||
|
vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Displace = {
|
||||||
|
/* name */ "Displace",
|
||||||
|
/* structName */ "DisplaceModifierData",
|
||||||
|
/* structSize */ sizeof(DisplaceModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ foreachIDLink,
|
||||||
|
};
|
||||||
1337
source/blender/modifiers/intern/MOD_edgesplit.c
Normal file
1337
source/blender/modifiers/intern/MOD_edgesplit.c
Normal file
File diff suppressed because it is too large
Load Diff
939
source/blender/modifiers/intern/MOD_explode.c
Normal file
939
source/blender/modifiers/intern/MOD_explode.c
Normal file
@@ -0,0 +1,939 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||||
|
|
||||||
|
emd->facepa=0;
|
||||||
|
emd->flag |= eExplodeFlag_Unborn+eExplodeFlag_Alive+eExplodeFlag_Dead;
|
||||||
|
}
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||||
|
|
||||||
|
if(emd->facepa) MEM_freeN(emd->facepa);
|
||||||
|
}
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||||
|
ExplodeModifierData *temd= (ExplodeModifierData*) target;
|
||||||
|
|
||||||
|
temd->facepa = 0;
|
||||||
|
temd->flag = emd->flag;
|
||||||
|
temd->protect = emd->protect;
|
||||||
|
temd->vgroup = emd->vgroup;
|
||||||
|
}
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
if(emd->vgroup)
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createFacepa(ExplodeModifierData *emd,
|
||||||
|
ParticleSystemModifierData *psmd,
|
||||||
|
Object *ob, DerivedMesh *dm)
|
||||||
|
{
|
||||||
|
ParticleSystem *psys=psmd->psys;
|
||||||
|
MFace *fa=0, *mface=0;
|
||||||
|
MVert *mvert = 0;
|
||||||
|
ParticleData *pa;
|
||||||
|
KDTree *tree;
|
||||||
|
float center[3], co[3];
|
||||||
|
int *facepa=0,*vertpa=0,totvert=0,totface=0,totpart=0;
|
||||||
|
int i,p,v1,v2,v3,v4=0;
|
||||||
|
|
||||||
|
mvert = dm->getVertArray(dm);
|
||||||
|
mface = dm->getFaceArray(dm);
|
||||||
|
totface= dm->getNumFaces(dm);
|
||||||
|
totvert= dm->getNumVerts(dm);
|
||||||
|
totpart= psmd->psys->totpart;
|
||||||
|
|
||||||
|
BLI_srandom(psys->seed);
|
||||||
|
|
||||||
|
if(emd->facepa)
|
||||||
|
MEM_freeN(emd->facepa);
|
||||||
|
|
||||||
|
facepa = emd->facepa = MEM_callocN(sizeof(int)*totface, "explode_facepa");
|
||||||
|
|
||||||
|
vertpa = MEM_callocN(sizeof(int)*totvert, "explode_vertpa");
|
||||||
|
|
||||||
|
/* initialize all faces & verts to no particle */
|
||||||
|
for(i=0; i<totface; i++)
|
||||||
|
facepa[i]=totpart;
|
||||||
|
|
||||||
|
for (i=0; i<totvert; i++)
|
||||||
|
vertpa[i]=totpart;
|
||||||
|
|
||||||
|
/* set protected verts */
|
||||||
|
if(emd->vgroup){
|
||||||
|
MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
float val;
|
||||||
|
if(dvert){
|
||||||
|
int defgrp_index= emd->vgroup-1;
|
||||||
|
for(i=0; i<totvert; i++, dvert++){
|
||||||
|
val = BLI_frand();
|
||||||
|
val = (1.0f-emd->protect)*val + emd->protect*0.5f;
|
||||||
|
if(val < defvert_find_weight(dvert, defgrp_index))
|
||||||
|
vertpa[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make tree of emitter locations */
|
||||||
|
tree=BLI_kdtree_new(totpart);
|
||||||
|
for(p=0,pa=psys->particles; p<totpart; p++,pa++){
|
||||||
|
psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
|
||||||
|
BLI_kdtree_insert(tree, p, co, NULL);
|
||||||
|
}
|
||||||
|
BLI_kdtree_balance(tree);
|
||||||
|
|
||||||
|
/* set face-particle-indexes to nearest particle to face center */
|
||||||
|
for(i=0,fa=mface; i<totface; i++,fa++){
|
||||||
|
add_v3_v3v3(center,mvert[fa->v1].co,mvert[fa->v2].co);
|
||||||
|
add_v3_v3v3(center,center,mvert[fa->v3].co);
|
||||||
|
if(fa->v4){
|
||||||
|
add_v3_v3v3(center,center,mvert[fa->v4].co);
|
||||||
|
mul_v3_fl(center,0.25);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mul_v3_fl(center,0.3333f);
|
||||||
|
|
||||||
|
p= BLI_kdtree_find_nearest(tree,center,NULL,NULL);
|
||||||
|
|
||||||
|
v1=vertpa[fa->v1];
|
||||||
|
v2=vertpa[fa->v2];
|
||||||
|
v3=vertpa[fa->v3];
|
||||||
|
if(fa->v4)
|
||||||
|
v4=vertpa[fa->v4];
|
||||||
|
|
||||||
|
if(v1>=0 && v2>=0 && v3>=0 && (fa->v4==0 || v4>=0))
|
||||||
|
facepa[i]=p;
|
||||||
|
|
||||||
|
if(v1>=0) vertpa[fa->v1]=p;
|
||||||
|
if(v2>=0) vertpa[fa->v2]=p;
|
||||||
|
if(v3>=0) vertpa[fa->v3]=p;
|
||||||
|
if(fa->v4 && v4>=0) vertpa[fa->v4]=p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vertpa) MEM_freeN(vertpa);
|
||||||
|
BLI_kdtree_free(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int edgesplit_get(EdgeHash *edgehash, int v1, int v2)
|
||||||
|
{
|
||||||
|
return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh * splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
|
||||||
|
DerivedMesh *splitdm;
|
||||||
|
MFace *mf=0,*df1=0,*df2=0,*df3=0;
|
||||||
|
MFace *mface=CDDM_get_faces(dm);
|
||||||
|
MVert *dupve, *mv;
|
||||||
|
EdgeHash *edgehash;
|
||||||
|
EdgeHashIterator *ehi;
|
||||||
|
int totvert=dm->getNumVerts(dm);
|
||||||
|
int totface=dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit");
|
||||||
|
int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
|
||||||
|
int *facepa = emd->facepa;
|
||||||
|
int *fs, totesplit=0,totfsplit=0,totin=0,curdupvert=0,curdupface=0,curdupin=0;
|
||||||
|
int i,j,v1,v2,v3,v4,esplit;
|
||||||
|
|
||||||
|
edgehash= BLI_edgehash_new();
|
||||||
|
|
||||||
|
/* recreate vertpa from facepa calculation */
|
||||||
|
for (i=0,mf=mface; i<totface; i++,mf++) {
|
||||||
|
vertpa[mf->v1]=facepa[i];
|
||||||
|
vertpa[mf->v2]=facepa[i];
|
||||||
|
vertpa[mf->v3]=facepa[i];
|
||||||
|
if(mf->v4)
|
||||||
|
vertpa[mf->v4]=facepa[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mark edges for splitting and how to split faces */
|
||||||
|
for (i=0,mf=mface,fs=facesplit; i<totface; i++,mf++,fs++) {
|
||||||
|
if(mf->v4){
|
||||||
|
v1=vertpa[mf->v1];
|
||||||
|
v2=vertpa[mf->v2];
|
||||||
|
v3=vertpa[mf->v3];
|
||||||
|
v4=vertpa[mf->v4];
|
||||||
|
|
||||||
|
if(v1!=v2){
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
|
||||||
|
(*fs)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(v2!=v3){
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
|
||||||
|
(*fs)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(v3!=v4){
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
|
||||||
|
(*fs)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(v1!=v4){
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
|
||||||
|
(*fs)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*fs==2){
|
||||||
|
if((v1==v2 && v3==v4) || (v1==v4 && v2==v3))
|
||||||
|
*fs=1;
|
||||||
|
else if(v1!=v2){
|
||||||
|
if(v1!=v4)
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
|
||||||
|
else
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(v1!=v4)
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
|
||||||
|
else
|
||||||
|
BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* count splits & reindex */
|
||||||
|
ehi= BLI_edgehashIterator_new(edgehash);
|
||||||
|
totesplit=totvert;
|
||||||
|
for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
|
||||||
|
BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
|
||||||
|
totesplit++;
|
||||||
|
}
|
||||||
|
BLI_edgehashIterator_free(ehi);
|
||||||
|
|
||||||
|
/* count new faces due to splitting */
|
||||||
|
for(i=0,fs=facesplit; i<totface; i++,fs++){
|
||||||
|
if(*fs==1)
|
||||||
|
totfsplit+=1;
|
||||||
|
else if(*fs==2)
|
||||||
|
totfsplit+=2;
|
||||||
|
else if(*fs==3)
|
||||||
|
totfsplit+=3;
|
||||||
|
else if(*fs==4){
|
||||||
|
totfsplit+=3;
|
||||||
|
|
||||||
|
mf=dm->getFaceData(dm,i,CD_MFACE);//CDDM_get_face(dm,i);
|
||||||
|
|
||||||
|
if(vertpa[mf->v1]!=vertpa[mf->v2] && vertpa[mf->v2]!=vertpa[mf->v3])
|
||||||
|
totin++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
splitdm= CDDM_from_template(dm, totesplit+totin, dm->getNumEdges(dm),totface+totfsplit);
|
||||||
|
|
||||||
|
/* copy new faces & verts (is it really this painful with custom data??) */
|
||||||
|
for(i=0; i<totvert; i++){
|
||||||
|
MVert source;
|
||||||
|
MVert *dest;
|
||||||
|
dm->getVert(dm, i, &source);
|
||||||
|
dest = CDDM_get_vert(splitdm, i);
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm, splitdm, i, i, 1);
|
||||||
|
*dest = source;
|
||||||
|
}
|
||||||
|
for(i=0; i<totface; i++){
|
||||||
|
MFace source;
|
||||||
|
MFace *dest;
|
||||||
|
dm->getFace(dm, i, &source);
|
||||||
|
dest = CDDM_get_face(splitdm, i);
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, splitdm, i, i, 1);
|
||||||
|
*dest = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* override original facepa (original pointer is saved in caller function) */
|
||||||
|
facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa");
|
||||||
|
memcpy(facepa,emd->facepa,totface*sizeof(int));
|
||||||
|
emd->facepa=facepa;
|
||||||
|
|
||||||
|
/* create new verts */
|
||||||
|
curdupvert=totvert;
|
||||||
|
ehi= BLI_edgehashIterator_new(edgehash);
|
||||||
|
for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
|
||||||
|
BLI_edgehashIterator_getKey(ehi, &i, &j);
|
||||||
|
esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
|
||||||
|
mv=CDDM_get_vert(splitdm,j);
|
||||||
|
dupve=CDDM_get_vert(splitdm,esplit);
|
||||||
|
|
||||||
|
DM_copy_vert_data(splitdm,splitdm,j,esplit,1);
|
||||||
|
|
||||||
|
*dupve=*mv;
|
||||||
|
|
||||||
|
mv=CDDM_get_vert(splitdm,i);
|
||||||
|
|
||||||
|
VECADD(dupve->co,dupve->co,mv->co);
|
||||||
|
mul_v3_fl(dupve->co,0.5);
|
||||||
|
}
|
||||||
|
BLI_edgehashIterator_free(ehi);
|
||||||
|
|
||||||
|
/* create new faces */
|
||||||
|
curdupface=totface;
|
||||||
|
curdupin=totesplit;
|
||||||
|
for(i=0,fs=facesplit; i<totface; i++,fs++){
|
||||||
|
if(*fs){
|
||||||
|
mf=CDDM_get_face(splitdm,i);
|
||||||
|
|
||||||
|
v1=vertpa[mf->v1];
|
||||||
|
v2=vertpa[mf->v2];
|
||||||
|
v3=vertpa[mf->v3];
|
||||||
|
v4=vertpa[mf->v4];
|
||||||
|
/* ouch! creating new faces & remapping them to new verts is no fun */
|
||||||
|
if(*fs==1){
|
||||||
|
df1=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df1=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
if(v1==v2){
|
||||||
|
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
mf->v3=df1->v2;
|
||||||
|
mf->v4=df1->v1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
mf->v2=df1->v1;
|
||||||
|
mf->v3=df1->v4;
|
||||||
|
}
|
||||||
|
|
||||||
|
facepa[i]=v1;
|
||||||
|
facepa[curdupface-1]=v3;
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface, (df1->v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
if(*fs==2){
|
||||||
|
df1=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df1=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df2=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df2=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
if(v1!=v2){
|
||||||
|
if(v1!=v4){
|
||||||
|
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df2->v1=df1->v3=mf->v2;
|
||||||
|
df2->v3=df1->v4=mf->v4;
|
||||||
|
df2->v2=mf->v3;
|
||||||
|
|
||||||
|
mf->v2=df1->v2;
|
||||||
|
mf->v3=df1->v1;
|
||||||
|
|
||||||
|
df2->v4=mf->v4=0;
|
||||||
|
|
||||||
|
facepa[i]=v1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
df1->v4=mf->v3;
|
||||||
|
df2->v2=mf->v3;
|
||||||
|
df2->v3=mf->v4;
|
||||||
|
|
||||||
|
mf->v1=df1->v2;
|
||||||
|
mf->v3=df1->v3;
|
||||||
|
|
||||||
|
df2->v4=mf->v4=0;
|
||||||
|
|
||||||
|
facepa[i]=v2;
|
||||||
|
}
|
||||||
|
facepa[curdupface-1]=facepa[curdupface-2]=v3;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(v1!=v4){
|
||||||
|
df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
df1->v2=mf->v3;
|
||||||
|
|
||||||
|
mf->v1=df1->v4;
|
||||||
|
mf->v2=df1->v3;
|
||||||
|
mf->v3=mf->v4;
|
||||||
|
|
||||||
|
df2->v4=mf->v4=0;
|
||||||
|
|
||||||
|
facepa[i]=v4;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
df1->v1=mf->v4;
|
||||||
|
df1->v2=mf->v2;
|
||||||
|
df2->v3=mf->v4;
|
||||||
|
|
||||||
|
mf->v1=df1->v4;
|
||||||
|
mf->v2=df1->v3;
|
||||||
|
|
||||||
|
df2->v4=mf->v4=0;
|
||||||
|
|
||||||
|
facepa[i]=v3;
|
||||||
|
}
|
||||||
|
|
||||||
|
facepa[curdupface-1]=facepa[curdupface-2]=v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
else if(*fs==3){
|
||||||
|
df1=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df1=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df2=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df2=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df3=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df3=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
if(v1==v2){
|
||||||
|
df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
df3->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
df3->v3=df2->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
df3->v2=mf->v3;
|
||||||
|
df2->v3=mf->v4;
|
||||||
|
df1->v4=df2->v4=df3->v4=0;
|
||||||
|
|
||||||
|
mf->v3=df1->v2;
|
||||||
|
mf->v4=df1->v1;
|
||||||
|
|
||||||
|
facepa[i]=facepa[curdupface-3]=v1;
|
||||||
|
facepa[curdupface-1]=v3;
|
||||||
|
facepa[curdupface-2]=v4;
|
||||||
|
}
|
||||||
|
else if(v2==v3){
|
||||||
|
df3->v1=df2->v3=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
df2->v2=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df3->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
|
||||||
|
df3->v3=mf->v4;
|
||||||
|
df2->v1=mf->v1;
|
||||||
|
df1->v4=df2->v4=df3->v4=0;
|
||||||
|
|
||||||
|
mf->v1=df1->v2;
|
||||||
|
mf->v4=df1->v3;
|
||||||
|
|
||||||
|
facepa[i]=facepa[curdupface-3]=v2;
|
||||||
|
facepa[curdupface-1]=v4;
|
||||||
|
facepa[curdupface-2]=v1;
|
||||||
|
}
|
||||||
|
else if(v3==v4){
|
||||||
|
df3->v2=df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df2->v3=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
df3->v3=df1->v3=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
|
||||||
|
df3->v1=mf->v1;
|
||||||
|
df2->v2=mf->v2;
|
||||||
|
df1->v4=df2->v4=df3->v4=0;
|
||||||
|
|
||||||
|
mf->v1=df1->v3;
|
||||||
|
mf->v2=df1->v2;
|
||||||
|
|
||||||
|
facepa[i]=facepa[curdupface-3]=v3;
|
||||||
|
facepa[curdupface-1]=v1;
|
||||||
|
facepa[curdupface-2]=v2;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
df3->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df3->v3=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
df2->v3=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
|
||||||
|
df3->v2=mf->v2;
|
||||||
|
df2->v2=mf->v3;
|
||||||
|
df1->v4=df2->v4=df3->v4=0;
|
||||||
|
|
||||||
|
mf->v2=df1->v1;
|
||||||
|
mf->v3=df1->v3;
|
||||||
|
|
||||||
|
facepa[i]=facepa[curdupface-3]=v1;
|
||||||
|
facepa[curdupface-1]=v2;
|
||||||
|
facepa[curdupface-2]=v3;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
else if(*fs==4){
|
||||||
|
if(v1!=v2 && v2!=v3){
|
||||||
|
|
||||||
|
/* set new vert to face center */
|
||||||
|
mv=CDDM_get_vert(splitdm,mf->v1);
|
||||||
|
dupve=CDDM_get_vert(splitdm,curdupin);
|
||||||
|
DM_copy_vert_data(splitdm,splitdm,mf->v1,curdupin,1);
|
||||||
|
*dupve=*mv;
|
||||||
|
|
||||||
|
mv=CDDM_get_vert(splitdm,mf->v2);
|
||||||
|
VECADD(dupve->co,dupve->co,mv->co);
|
||||||
|
mv=CDDM_get_vert(splitdm,mf->v3);
|
||||||
|
VECADD(dupve->co,dupve->co,mv->co);
|
||||||
|
mv=CDDM_get_vert(splitdm,mf->v4);
|
||||||
|
VECADD(dupve->co,dupve->co,mv->co);
|
||||||
|
mul_v3_fl(dupve->co,0.25);
|
||||||
|
|
||||||
|
|
||||||
|
df1=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df1=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df2=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df2=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df3=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df3=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df3->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
|
||||||
|
df2->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
df3->v4=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
|
||||||
|
df3->v1=df2->v2=df1->v4=curdupin;
|
||||||
|
|
||||||
|
mf->v2=df1->v1;
|
||||||
|
mf->v3=curdupin;
|
||||||
|
mf->v4=df2->v1;
|
||||||
|
|
||||||
|
curdupin++;
|
||||||
|
|
||||||
|
facepa[i]=v1;
|
||||||
|
facepa[curdupface-3]=v2;
|
||||||
|
facepa[curdupface-2]=v3;
|
||||||
|
facepa[curdupface-1]=v4;
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
df1=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df1=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df2=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df2=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
df3=CDDM_get_face(splitdm,curdupface);
|
||||||
|
DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
|
||||||
|
*df3=*mf;
|
||||||
|
curdupface++;
|
||||||
|
|
||||||
|
if(v2==v3){
|
||||||
|
df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df3->v1=df1->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
df2->v1=df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
|
||||||
|
df3->v3=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
|
||||||
|
df3->v2=mf->v3;
|
||||||
|
df3->v4=0;
|
||||||
|
|
||||||
|
mf->v2=df1->v1;
|
||||||
|
mf->v3=df1->v4;
|
||||||
|
mf->v4=0;
|
||||||
|
|
||||||
|
facepa[i]=v1;
|
||||||
|
facepa[curdupface-3]=facepa[curdupface-2]=v2;
|
||||||
|
facepa[curdupface-1]=v3;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
df3->v1=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
|
||||||
|
df2->v4=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
|
||||||
|
df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
|
||||||
|
|
||||||
|
df3->v3=df2->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
|
||||||
|
|
||||||
|
df3->v4=0;
|
||||||
|
|
||||||
|
mf->v1=df1->v4;
|
||||||
|
mf->v2=df1->v3;
|
||||||
|
mf->v3=mf->v4;
|
||||||
|
mf->v4=0;
|
||||||
|
|
||||||
|
facepa[i]=v4;
|
||||||
|
facepa[curdupface-3]=facepa[curdupface-2]=v1;
|
||||||
|
facepa[curdupface-1]=v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
|
||||||
|
test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_index_face(df1, &splitdm->faceData, i, (df1->v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_edgehash_free(edgehash, NULL);
|
||||||
|
MEM_freeN(facesplit);
|
||||||
|
MEM_freeN(vertpa);
|
||||||
|
|
||||||
|
return splitdm;
|
||||||
|
|
||||||
|
}
|
||||||
|
static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
|
||||||
|
ParticleSystemModifierData *psmd, Scene *scene, Object *ob,
|
||||||
|
DerivedMesh *to_explode)
|
||||||
|
{
|
||||||
|
DerivedMesh *explode, *dm=to_explode;
|
||||||
|
MFace *mf=0, *mface;
|
||||||
|
ParticleSettings *part=psmd->psys->part;
|
||||||
|
ParticleSimulationData sim = {scene, ob, psmd->psys, psmd};
|
||||||
|
ParticleData *pa=NULL, *pars=psmd->psys->particles;
|
||||||
|
ParticleKey state;
|
||||||
|
EdgeHash *vertpahash;
|
||||||
|
EdgeHashIterator *ehi;
|
||||||
|
float *vertco=0, imat[4][4];
|
||||||
|
float loc0[3], nor[3];
|
||||||
|
float timestep, cfra;
|
||||||
|
int *facepa=emd->facepa;
|
||||||
|
int totdup=0,totvert=0,totface=0,totpart=0;
|
||||||
|
int i, j, v, mindex=0;
|
||||||
|
|
||||||
|
totface= dm->getNumFaces(dm);
|
||||||
|
totvert= dm->getNumVerts(dm);
|
||||||
|
mface= dm->getFaceArray(dm);
|
||||||
|
totpart= psmd->psys->totpart;
|
||||||
|
|
||||||
|
timestep= psys_get_timestep(&sim);
|
||||||
|
|
||||||
|
//if(part->flag & PART_GLOB_TIME)
|
||||||
|
cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
|
||||||
|
//else
|
||||||
|
// cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
|
||||||
|
|
||||||
|
/* hash table for vertice <-> particle relations */
|
||||||
|
vertpahash= BLI_edgehash_new();
|
||||||
|
|
||||||
|
for (i=0; i<totface; i++) {
|
||||||
|
/* do mindex + totvert to ensure the vertex index to be the first
|
||||||
|
* with BLI_edgehashIterator_getKey */
|
||||||
|
if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time)
|
||||||
|
mindex = totvert+totpart;
|
||||||
|
else
|
||||||
|
mindex = totvert+facepa[i];
|
||||||
|
|
||||||
|
mf= &mface[i];
|
||||||
|
|
||||||
|
/* set face vertices to exist in particle group */
|
||||||
|
BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL);
|
||||||
|
BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL);
|
||||||
|
BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL);
|
||||||
|
if(mf->v4)
|
||||||
|
BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make new vertice indexes & count total vertices after duplication */
|
||||||
|
ehi= BLI_edgehashIterator_new(vertpahash);
|
||||||
|
for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
|
||||||
|
BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup));
|
||||||
|
totdup++;
|
||||||
|
}
|
||||||
|
BLI_edgehashIterator_free(ehi);
|
||||||
|
|
||||||
|
/* the final duplicated vertices */
|
||||||
|
explode= CDDM_from_template(dm, totdup, 0,totface);
|
||||||
|
/*dupvert= CDDM_get_verts(explode);*/
|
||||||
|
|
||||||
|
/* getting back to object space */
|
||||||
|
invert_m4_m4(imat,ob->obmat);
|
||||||
|
|
||||||
|
psmd->psys->lattice = psys_get_lattice(&sim);
|
||||||
|
|
||||||
|
/* duplicate & displace vertices */
|
||||||
|
ehi= BLI_edgehashIterator_new(vertpahash);
|
||||||
|
for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
|
||||||
|
MVert source;
|
||||||
|
MVert *dest;
|
||||||
|
|
||||||
|
/* get particle + vertex from hash */
|
||||||
|
BLI_edgehashIterator_getKey(ehi, &j, &i);
|
||||||
|
i -= totvert;
|
||||||
|
v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
|
||||||
|
|
||||||
|
dm->getVert(dm, j, &source);
|
||||||
|
dest = CDDM_get_vert(explode,v);
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm,explode,j,v,1);
|
||||||
|
*dest = source;
|
||||||
|
|
||||||
|
if(i!=totpart) {
|
||||||
|
/* get particle */
|
||||||
|
pa= pars+i;
|
||||||
|
|
||||||
|
/* get particle state */
|
||||||
|
psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
|
||||||
|
mul_m4_v3(ob->obmat,loc0);
|
||||||
|
|
||||||
|
state.time=cfra;
|
||||||
|
psys_get_particle_state(&sim, i, &state, 1);
|
||||||
|
|
||||||
|
vertco=CDDM_get_vert(explode,v)->co;
|
||||||
|
|
||||||
|
mul_m4_v3(ob->obmat,vertco);
|
||||||
|
|
||||||
|
VECSUB(vertco,vertco,loc0);
|
||||||
|
|
||||||
|
/* apply rotation, size & location */
|
||||||
|
mul_qt_v3(state.rot,vertco);
|
||||||
|
if(emd->flag & eExplodeFlag_PaSize)
|
||||||
|
mul_v3_fl(vertco,pa->size);
|
||||||
|
VECADD(vertco,vertco,state.co);
|
||||||
|
|
||||||
|
mul_m4_v3(imat,vertco);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_edgehashIterator_free(ehi);
|
||||||
|
|
||||||
|
/*map new vertices to faces*/
|
||||||
|
for (i=0; i<totface; i++) {
|
||||||
|
MFace source;
|
||||||
|
int orig_v4;
|
||||||
|
|
||||||
|
if(facepa[i]!=totpart)
|
||||||
|
{
|
||||||
|
pa=pars+facepa[i];
|
||||||
|
|
||||||
|
if(pa->alive==PARS_UNBORN && (emd->flag&eExplodeFlag_Unborn)==0) continue;
|
||||||
|
if(pa->alive==PARS_ALIVE && (emd->flag&eExplodeFlag_Alive)==0) continue;
|
||||||
|
if(pa->alive==PARS_DEAD && (emd->flag&eExplodeFlag_Dead)==0) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm->getFace(dm,i,&source);
|
||||||
|
mf=CDDM_get_face(explode,i);
|
||||||
|
|
||||||
|
orig_v4 = source.v4;
|
||||||
|
|
||||||
|
if(facepa[i]!=totpart && cfra <= pa->time)
|
||||||
|
mindex = totvert+totpart;
|
||||||
|
else
|
||||||
|
mindex = totvert+facepa[i];
|
||||||
|
|
||||||
|
source.v1 = edgesplit_get(vertpahash, source.v1, mindex);
|
||||||
|
source.v2 = edgesplit_get(vertpahash, source.v2, mindex);
|
||||||
|
source.v3 = edgesplit_get(vertpahash, source.v3, mindex);
|
||||||
|
if(source.v4)
|
||||||
|
source.v4 = edgesplit_get(vertpahash, source.v4, mindex);
|
||||||
|
|
||||||
|
DM_copy_face_data(dm,explode,i,i,1);
|
||||||
|
|
||||||
|
*mf = source;
|
||||||
|
|
||||||
|
test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
BLI_edgehash_free(vertpahash, NULL);
|
||||||
|
|
||||||
|
/* finalization */
|
||||||
|
CDDM_calc_edges(explode);
|
||||||
|
CDDM_calc_normals(explode);
|
||||||
|
|
||||||
|
if(psmd->psys->lattice){
|
||||||
|
end_latt_deform(psmd->psys->lattice);
|
||||||
|
psmd->psys->lattice= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return explode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParticleSystemModifierData * findPrecedingParticlesystem(Object *ob, ModifierData *emd)
|
||||||
|
{
|
||||||
|
ModifierData *md;
|
||||||
|
ParticleSystemModifierData *psmd=0;
|
||||||
|
|
||||||
|
for (md=ob->modifiers.first; emd!=md; md=md->next){
|
||||||
|
if(md->type==eModifierType_ParticleSystem)
|
||||||
|
psmd= (ParticleSystemModifierData*) md;
|
||||||
|
}
|
||||||
|
return psmd;
|
||||||
|
}
|
||||||
|
static DerivedMesh * applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||||
|
ParticleSystemModifierData *psmd=findPrecedingParticlesystem(ob,md);
|
||||||
|
|
||||||
|
if(psmd){
|
||||||
|
ParticleSystem * psys=psmd->psys;
|
||||||
|
|
||||||
|
if(psys==0 || psys->totpart==0) return derivedData;
|
||||||
|
if(psys->part==0 || psys->particles==0) return derivedData;
|
||||||
|
if(psmd->dm==0) return derivedData;
|
||||||
|
|
||||||
|
/* 1. find faces to be exploded if needed */
|
||||||
|
if(emd->facepa==0
|
||||||
|
|| psmd->flag&eParticleSystemFlag_Pars
|
||||||
|
|| emd->flag&eExplodeFlag_CalcFaces
|
||||||
|
|| MEM_allocN_len(emd->facepa)/sizeof(int) != dm->getNumFaces(dm)){
|
||||||
|
if(psmd->flag & eParticleSystemFlag_Pars)
|
||||||
|
psmd->flag &= ~eParticleSystemFlag_Pars;
|
||||||
|
|
||||||
|
if(emd->flag & eExplodeFlag_CalcFaces)
|
||||||
|
emd->flag &= ~eExplodeFlag_CalcFaces;
|
||||||
|
|
||||||
|
createFacepa(emd,psmd,ob,derivedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. create new mesh */
|
||||||
|
if(emd->flag & eExplodeFlag_EdgeSplit){
|
||||||
|
int *facepa = emd->facepa;
|
||||||
|
DerivedMesh *splitdm=splitEdges(emd,dm);
|
||||||
|
DerivedMesh *explode=explodeMesh(emd, psmd, md->scene, ob, splitdm);
|
||||||
|
|
||||||
|
MEM_freeN(emd->facepa);
|
||||||
|
emd->facepa=facepa;
|
||||||
|
splitdm->release(splitdm);
|
||||||
|
return explode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return explodeMesh(emd, psmd, md->scene, ob, derivedData);
|
||||||
|
}
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Explode = {
|
||||||
|
/* name */ "Explode",
|
||||||
|
/* structName */ "ExplodeModifierData",
|
||||||
|
/* structSize */ sizeof(ExplodeModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh,
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
198
source/blender/modifiers/intern/MOD_fluidsim.c
Normal file
198
source/blender/modifiers/intern/MOD_fluidsim.c
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_fluidsim_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Fluidsim */
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
|
||||||
|
|
||||||
|
fluidsim_init(fluidmd);
|
||||||
|
}
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
|
||||||
|
|
||||||
|
fluidsim_free(fluidmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
|
||||||
|
FluidsimModifierData *tfluidmd= (FluidsimModifierData*) target;
|
||||||
|
|
||||||
|
if(tfluidmd->fss)
|
||||||
|
MEM_freeN(tfluidmd->fss);
|
||||||
|
|
||||||
|
tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static DerivedMesh * applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
|
||||||
|
DerivedMesh *result = NULL;
|
||||||
|
|
||||||
|
/* check for alloc failing */
|
||||||
|
if(!fluidmd->fss)
|
||||||
|
{
|
||||||
|
initData(md);
|
||||||
|
|
||||||
|
if(!fluidmd->fss)
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = fluidsimModifier_do(fluidmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
|
||||||
|
Base *base;
|
||||||
|
|
||||||
|
if(fluidmd && fluidmd->fss)
|
||||||
|
{
|
||||||
|
if(fluidmd->fss->type == OB_FLUIDSIM_DOMAIN)
|
||||||
|
{
|
||||||
|
for(base = scene->base.first; base; base= base->next)
|
||||||
|
{
|
||||||
|
Object *ob1= base->object;
|
||||||
|
if(ob1 != ob)
|
||||||
|
{
|
||||||
|
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob1, eModifierType_Fluidsim);
|
||||||
|
|
||||||
|
// only put dependancies from NON-DOMAIN fluids in here
|
||||||
|
if(fluidmdtmp && fluidmdtmp->fss && (fluidmdtmp->fss->type!=OB_FLUIDSIM_DOMAIN))
|
||||||
|
{
|
||||||
|
DagNode *curNode = dag_get_node(forest, ob1);
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Fluidsim Object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Fluidsim = {
|
||||||
|
/* name */ "Fluidsim",
|
||||||
|
/* structName */ "FluidsimModifierData",
|
||||||
|
/* structSize */ sizeof(FluidsimModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_RequiresOriginalData
|
||||||
|
| eModifierTypeFlag_Single,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
669
source/blender/modifiers/intern/MOD_fluidsim_util.c
Normal file
669
source/blender/modifiers/intern/MOD_fluidsim_util.c
Normal file
@@ -0,0 +1,669 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
// headers for fluidsim bobj meshes
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "LBM_fluidsim.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_fluidsim_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_mesh_types.h"
|
||||||
|
#include "DNA_meshdata_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
#include "DNA_object_force.h" // for pointcache
|
||||||
|
#include "DNA_object_types.h"
|
||||||
|
#include "DNA_particle_types.h"
|
||||||
|
#include "DNA_scene_types.h" // N_T
|
||||||
|
|
||||||
|
#include "BLI_math.h"
|
||||||
|
#include "BLI_blenlib.h"
|
||||||
|
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_customdata.h"
|
||||||
|
#include "BKE_DerivedMesh.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_utildefines.h"
|
||||||
|
|
||||||
|
#include "BLO_sys_types.h"
|
||||||
|
|
||||||
|
void fluidsim_init(FluidsimModifierData *fluidmd)
|
||||||
|
{
|
||||||
|
#ifndef DISABLE_ELBEEM
|
||||||
|
if(fluidmd)
|
||||||
|
{
|
||||||
|
FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings");
|
||||||
|
|
||||||
|
fluidmd->fss = fss;
|
||||||
|
|
||||||
|
if(!fss)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fss->fmd = fluidmd;
|
||||||
|
fss->type = OB_FLUIDSIM_ENABLE;
|
||||||
|
fss->show_advancedoptions = 0;
|
||||||
|
|
||||||
|
fss->resolutionxyz = 65;
|
||||||
|
fss->previewresxyz = 45;
|
||||||
|
fss->realsize = 0.5;
|
||||||
|
fss->guiDisplayMode = 2; // preview
|
||||||
|
fss->renderDisplayMode = 3; // render
|
||||||
|
|
||||||
|
fss->viscosityMode = 2; // default to water
|
||||||
|
fss->viscosityValue = 1.0;
|
||||||
|
fss->viscosityExponent = 6;
|
||||||
|
|
||||||
|
// dg TODO: change this to []
|
||||||
|
fss->gravx = 0.0;
|
||||||
|
fss->gravy = 0.0;
|
||||||
|
fss->gravz = -9.81;
|
||||||
|
fss->animStart = 0.0;
|
||||||
|
fss->animEnd = 4.0;
|
||||||
|
fss->gstar = 0.005; // used as normgstar
|
||||||
|
fss->maxRefine = -1;
|
||||||
|
// maxRefine is set according to resolutionxyz during bake
|
||||||
|
|
||||||
|
// fluid/inflow settings
|
||||||
|
// fss->iniVel --> automatically set to 0
|
||||||
|
|
||||||
|
/* elubie: changed this to default to the same dir as the render output
|
||||||
|
to prevent saving to C:\ on Windows */
|
||||||
|
BLI_strncpy(fss->surfdataPath, btempdir, FILE_MAX);
|
||||||
|
|
||||||
|
// first init of bounding box
|
||||||
|
// no bounding box needed
|
||||||
|
|
||||||
|
// todo - reuse default init from elbeem!
|
||||||
|
fss->typeFlags = OB_FSBND_PARTSLIP;
|
||||||
|
fss->domainNovecgen = 0;
|
||||||
|
fss->volumeInitType = 1; // volume
|
||||||
|
fss->partSlipValue = 0.2;
|
||||||
|
|
||||||
|
fss->generateTracers = 0;
|
||||||
|
fss->generateParticles = 0.0;
|
||||||
|
fss->surfaceSmoothing = 1.0;
|
||||||
|
fss->surfaceSubdivs = 0.0;
|
||||||
|
fss->particleInfSize = 0.0;
|
||||||
|
fss->particleInfAlpha = 0.0;
|
||||||
|
|
||||||
|
// init fluid control settings
|
||||||
|
fss->attractforceStrength = 0.2;
|
||||||
|
fss->attractforceRadius = 0.75;
|
||||||
|
fss->velocityforceStrength = 0.2;
|
||||||
|
fss->velocityforceRadius = 0.75;
|
||||||
|
fss->cpsTimeStart = fss->animStart;
|
||||||
|
fss->cpsTimeEnd = fss->animEnd;
|
||||||
|
fss->cpsQuality = 10.0; // 1.0 / 10.0 => means 0.1 width
|
||||||
|
|
||||||
|
/*
|
||||||
|
BAD TODO: this is done in buttons_object.c in the moment
|
||||||
|
Mesh *mesh = ob->data;
|
||||||
|
// calculate bounding box
|
||||||
|
fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// (ab)used to store velocities
|
||||||
|
fss->meshSurfNormals = NULL;
|
||||||
|
|
||||||
|
fss->lastgoodframe = -1;
|
||||||
|
|
||||||
|
fss->flag |= OB_FLUIDSIM_ACTIVE;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fluidsim_free(FluidsimModifierData *fluidmd)
|
||||||
|
{
|
||||||
|
#ifndef DISABLE_ELBEEM
|
||||||
|
if(fluidmd)
|
||||||
|
{
|
||||||
|
if(fluidmd->fss->meshSurfNormals)
|
||||||
|
{
|
||||||
|
MEM_freeN(fluidmd->fss->meshSurfNormals);
|
||||||
|
fluidmd->fss->meshSurfNormals = NULL;
|
||||||
|
}
|
||||||
|
MEM_freeN(fluidmd->fss);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_ELBEEM
|
||||||
|
/* read .bobj.gz file into a fluidsimDerivedMesh struct */
|
||||||
|
DerivedMesh *fluidsim_read_obj(char *filename)
|
||||||
|
{
|
||||||
|
int wri,i,j;
|
||||||
|
float wrf;
|
||||||
|
int gotBytes;
|
||||||
|
gzFile gzf;
|
||||||
|
int numverts = 0, numfaces = 0;
|
||||||
|
DerivedMesh *dm = NULL;
|
||||||
|
MFace *mface;
|
||||||
|
MVert *mvert;
|
||||||
|
short *normals;
|
||||||
|
|
||||||
|
// ------------------------------------------------
|
||||||
|
// get numverts + numfaces first
|
||||||
|
// ------------------------------------------------
|
||||||
|
gzf = gzopen(filename, "rb");
|
||||||
|
if (!gzf)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read numverts
|
||||||
|
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
||||||
|
numverts = wri;
|
||||||
|
|
||||||
|
// skip verts
|
||||||
|
for(i=0; i<numverts*3; i++)
|
||||||
|
{
|
||||||
|
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// read number of normals
|
||||||
|
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
||||||
|
|
||||||
|
// skip normals
|
||||||
|
for(i=0; i<numverts*3; i++)
|
||||||
|
{
|
||||||
|
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get no. of triangles */
|
||||||
|
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
||||||
|
numfaces = wri;
|
||||||
|
|
||||||
|
gzclose( gzf );
|
||||||
|
// ------------------------------------------------
|
||||||
|
|
||||||
|
if(!numfaces || !numverts)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
gzf = gzopen(filename, "rb");
|
||||||
|
if (!gzf)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm = CDDM_new(numverts, 0, numfaces);
|
||||||
|
|
||||||
|
if(!dm)
|
||||||
|
{
|
||||||
|
gzclose( gzf );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read numverts
|
||||||
|
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
||||||
|
|
||||||
|
// read vertex position from file
|
||||||
|
mvert = CDDM_get_verts(dm);
|
||||||
|
for(i=0; i<numverts; i++)
|
||||||
|
{
|
||||||
|
MVert *mv = &mvert[i];
|
||||||
|
|
||||||
|
for(j=0; j<3; j++)
|
||||||
|
{
|
||||||
|
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
||||||
|
mv->co[j] = wrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be the same as numverts
|
||||||
|
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
||||||
|
if(wri != numverts)
|
||||||
|
{
|
||||||
|
if(dm)
|
||||||
|
dm->release(dm);
|
||||||
|
gzclose( gzf );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
normals = MEM_callocN(sizeof(short) * numverts * 3, "fluid_tmp_normals" );
|
||||||
|
if(!normals)
|
||||||
|
{
|
||||||
|
if(dm)
|
||||||
|
dm->release(dm);
|
||||||
|
gzclose( gzf );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read normals from file (but don't save them yet)
|
||||||
|
for(i=0; i<numverts*3; i++)
|
||||||
|
{
|
||||||
|
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
|
||||||
|
normals[i] = (short)(wrf*32767.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read no. of triangles */
|
||||||
|
gotBytes = gzread(gzf, &wri, sizeof(wri));
|
||||||
|
|
||||||
|
if(wri!=numfaces)
|
||||||
|
printf("Fluidsim: error in reading data from file.\n");
|
||||||
|
|
||||||
|
// read triangles from file
|
||||||
|
mface = CDDM_get_faces(dm);
|
||||||
|
for(i=0; i<numfaces; i++)
|
||||||
|
{
|
||||||
|
int face[4];
|
||||||
|
MFace *mf = &mface[i];
|
||||||
|
|
||||||
|
gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] ));
|
||||||
|
gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] ));
|
||||||
|
gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] ));
|
||||||
|
face[3] = 0;
|
||||||
|
|
||||||
|
// check if 3rd vertex has index 0 (not allowed in blender)
|
||||||
|
if(face[2])
|
||||||
|
{
|
||||||
|
mf->v1 = face[0];
|
||||||
|
mf->v2 = face[1];
|
||||||
|
mf->v3 = face[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mf->v1 = face[1];
|
||||||
|
mf->v2 = face[2];
|
||||||
|
mf->v3 = face[0];
|
||||||
|
}
|
||||||
|
mf->v4 = face[3];
|
||||||
|
|
||||||
|
test_index_face(mf, NULL, 0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
gzclose( gzf );
|
||||||
|
|
||||||
|
CDDM_calc_edges(dm);
|
||||||
|
|
||||||
|
CDDM_apply_vert_normals(dm, (short (*)[3])normals);
|
||||||
|
MEM_freeN(normals);
|
||||||
|
|
||||||
|
// CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
|
||||||
|
/*RET*/ float start[3], /*RET*/ float size[3] )
|
||||||
|
{
|
||||||
|
float bbsx=0.0, bbsy=0.0, bbsz=0.0;
|
||||||
|
float bbex=1.0, bbey=1.0, bbez=1.0;
|
||||||
|
int i;
|
||||||
|
float vec[3];
|
||||||
|
|
||||||
|
if(totvert == 0) {
|
||||||
|
zero_v3(start);
|
||||||
|
zero_v3(size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vec, mvert[0].co);
|
||||||
|
mul_m4_v3(obmat, vec);
|
||||||
|
bbsx = vec[0]; bbsy = vec[1]; bbsz = vec[2];
|
||||||
|
bbex = vec[0]; bbey = vec[1]; bbez = vec[2];
|
||||||
|
|
||||||
|
for(i = 1; i < totvert; i++) {
|
||||||
|
VECCOPY(vec, mvert[i].co);
|
||||||
|
mul_m4_v3(obmat, vec);
|
||||||
|
|
||||||
|
if(vec[0] < bbsx){ bbsx= vec[0]; }
|
||||||
|
if(vec[1] < bbsy){ bbsy= vec[1]; }
|
||||||
|
if(vec[2] < bbsz){ bbsz= vec[2]; }
|
||||||
|
if(vec[0] > bbex){ bbex= vec[0]; }
|
||||||
|
if(vec[1] > bbey){ bbey= vec[1]; }
|
||||||
|
if(vec[2] > bbez){ bbez= vec[2]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// return values...
|
||||||
|
if(start) {
|
||||||
|
start[0] = bbsx;
|
||||||
|
start[1] = bbsy;
|
||||||
|
start[2] = bbsz;
|
||||||
|
}
|
||||||
|
if(size) {
|
||||||
|
size[0] = bbex-bbsx;
|
||||||
|
size[1] = bbey-bbsy;
|
||||||
|
size[2] = bbez-bbsz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
// old interface
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void fluid_estimate_memory(Object *ob, FluidsimSettings *fss, char *value)
|
||||||
|
{
|
||||||
|
Mesh *mesh;
|
||||||
|
|
||||||
|
value[0]= '\0';
|
||||||
|
|
||||||
|
if(ob->type == OB_MESH) {
|
||||||
|
/* use mesh bounding box and object scaling */
|
||||||
|
mesh= ob->data;
|
||||||
|
|
||||||
|
fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
|
||||||
|
elbeemEstimateMemreq(fss->resolutionxyz, fss->bbSize[0],fss->bbSize[1],fss->bbSize[2], fss->maxRefine, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
|
||||||
|
void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename)
|
||||||
|
{
|
||||||
|
int wri, i, j;
|
||||||
|
float wrf;
|
||||||
|
gzFile gzf;
|
||||||
|
FluidsimSettings *fss = fluidmd->fss;
|
||||||
|
int len = strlen(filename);
|
||||||
|
int totvert = dm->getNumVerts(dm);
|
||||||
|
float *velarray = NULL;
|
||||||
|
|
||||||
|
// mesh and vverts have to be valid from loading...
|
||||||
|
|
||||||
|
if(fss->meshSurfNormals)
|
||||||
|
MEM_freeN(fss->meshSurfNormals);
|
||||||
|
|
||||||
|
if(len<7)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fss->domainNovecgen>0) return;
|
||||||
|
|
||||||
|
// abusing pointer to hold an array of 3d-velocities
|
||||||
|
fss->meshSurfNormals = MEM_callocN(sizeof(float)*3*dm->getNumVerts(dm), "Fluidsim_velocities");
|
||||||
|
// abusing pointer to hold an INT
|
||||||
|
fss->meshSurface = SET_INT_IN_POINTER(totvert);
|
||||||
|
|
||||||
|
velarray = (float *)fss->meshSurfNormals;
|
||||||
|
|
||||||
|
// .bobj.gz , correct filename
|
||||||
|
// 87654321
|
||||||
|
filename[len-6] = 'v';
|
||||||
|
filename[len-5] = 'e';
|
||||||
|
filename[len-4] = 'l';
|
||||||
|
|
||||||
|
gzf = gzopen(filename, "rb");
|
||||||
|
if (!gzf)
|
||||||
|
{
|
||||||
|
MEM_freeN(fss->meshSurfNormals);
|
||||||
|
fss->meshSurfNormals = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gzread(gzf, &wri, sizeof( wri ));
|
||||||
|
if(wri != totvert)
|
||||||
|
{
|
||||||
|
MEM_freeN(fss->meshSurfNormals);
|
||||||
|
fss->meshSurfNormals = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<totvert;i++)
|
||||||
|
{
|
||||||
|
for(j=0; j<3; j++)
|
||||||
|
{
|
||||||
|
gzread(gzf, &wrf, sizeof( wrf ));
|
||||||
|
velarray[3*i + j] = wrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gzclose(gzf);
|
||||||
|
}
|
||||||
|
|
||||||
|
DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
|
||||||
|
{
|
||||||
|
int displaymode = 0;
|
||||||
|
int curFrame = framenr - 1 /*scene->r.sfra*/; /* start with 0 at start frame */
|
||||||
|
char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR];
|
||||||
|
FluidsimSettings *fss = fluidmd->fss;
|
||||||
|
DerivedMesh *dm = NULL;
|
||||||
|
MFace *mface;
|
||||||
|
int numfaces;
|
||||||
|
int mat_nr, flag, i;
|
||||||
|
|
||||||
|
if(!useRenderParams) {
|
||||||
|
displaymode = fss->guiDisplayMode;
|
||||||
|
} else {
|
||||||
|
displaymode = fss->renderDisplayMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(targetDir, fss->surfdataPath, FILE_MAXDIR);
|
||||||
|
|
||||||
|
// use preview or final mesh?
|
||||||
|
if(displaymode==1)
|
||||||
|
{
|
||||||
|
// just display original object
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if(displaymode==2)
|
||||||
|
{
|
||||||
|
strcat(targetDir,"fluidsurface_preview_####");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // 3
|
||||||
|
strcat(targetDir,"fluidsurface_final_####");
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_path_abs(targetDir, G.sce);
|
||||||
|
BLI_path_frame(targetDir, curFrame, 0); // fixed #frame-no
|
||||||
|
|
||||||
|
strcpy(targetFile,targetDir);
|
||||||
|
strcat(targetFile, ".bobj.gz");
|
||||||
|
|
||||||
|
dm = fluidsim_read_obj(targetFile);
|
||||||
|
|
||||||
|
if(!dm)
|
||||||
|
{
|
||||||
|
// switch, abort background rendering when fluidsim mesh is missing
|
||||||
|
const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp
|
||||||
|
|
||||||
|
if(G.background==1) {
|
||||||
|
if(getenv(strEnvName2)) {
|
||||||
|
int elevel = atoi(getenv(strEnvName2));
|
||||||
|
if(elevel>0) {
|
||||||
|
printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",strEnvName2, targetFile);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// display org. object upon failure which is in dm
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign material + flags to new dm
|
||||||
|
mface = orgdm->getFaceArray(orgdm);
|
||||||
|
mat_nr = mface[0].mat_nr;
|
||||||
|
flag = mface[0].flag;
|
||||||
|
|
||||||
|
mface = dm->getFaceArray(dm);
|
||||||
|
numfaces = dm->getNumFaces(dm);
|
||||||
|
for(i=0; i<numfaces; i++)
|
||||||
|
{
|
||||||
|
mface[i].mat_nr = mat_nr;
|
||||||
|
mface[i].flag = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load vertex velocities, if they exist...
|
||||||
|
// TODO? use generate flag as loading flag as well?
|
||||||
|
// warning, needs original .bobj.gz mesh loading filename
|
||||||
|
if(displaymode==3)
|
||||||
|
{
|
||||||
|
fluidsim_read_vel_cache(fluidmd, dm, targetFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fss->meshSurfNormals)
|
||||||
|
MEM_freeN(fss->meshSurfNormals);
|
||||||
|
|
||||||
|
fss->meshSurfNormals = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DISABLE_ELBEEM
|
||||||
|
|
||||||
|
DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
#ifndef DISABLE_ELBEEM
|
||||||
|
DerivedMesh *result = NULL;
|
||||||
|
int framenr;
|
||||||
|
FluidsimSettings *fss = NULL;
|
||||||
|
|
||||||
|
framenr= (int)scene->r.cfra;
|
||||||
|
|
||||||
|
// only handle fluidsim domains
|
||||||
|
if(fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN))
|
||||||
|
return dm;
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
if(!fluidmd || (fluidmd && !fluidmd->fss))
|
||||||
|
return dm;
|
||||||
|
|
||||||
|
fss = fluidmd->fss;
|
||||||
|
|
||||||
|
// timescale not supported yet
|
||||||
|
// clmd->sim_parms->timescale= timescale;
|
||||||
|
|
||||||
|
// support reversing of baked fluid frames here
|
||||||
|
if((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0))
|
||||||
|
{
|
||||||
|
framenr = fss->lastgoodframe - framenr + 1;
|
||||||
|
CLAMP(framenr, 1, fss->lastgoodframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try to read from cache */
|
||||||
|
if(((fss->lastgoodframe >= framenr) || (fss->lastgoodframe < 0)) && (result = fluidsim_read_cache(ob, dm, fluidmd, framenr, useRenderParams)))
|
||||||
|
{
|
||||||
|
// fss->lastgoodframe = framenr; // set also in src/fluidsim.c
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// display last known good frame
|
||||||
|
if(fss->lastgoodframe >= 0)
|
||||||
|
{
|
||||||
|
if((result = fluidsim_read_cache(ob, dm, fluidmd, fss->lastgoodframe, useRenderParams)))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// it was supposed to be a valid frame but it isn't!
|
||||||
|
fss->lastgoodframe = framenr - 1;
|
||||||
|
|
||||||
|
|
||||||
|
// this could be likely the case when you load an old fluidsim
|
||||||
|
if((result = fluidsim_read_cache(ob, dm, fluidmd, fss->lastgoodframe, useRenderParams)))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CDDM_copy(dm);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dm;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* BKE_shrinkwrap.h
|
* $Id: BKE_fluidsim.h 26841 2010-02-12 13:34:04Z campbellbarton $
|
||||||
*
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* The Original Code is Copyright (C) Blender Foundation.
|
* The Original Code is Copyright (C) Blender Foundation
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* The Original Code is: all of this file.
|
* The Original Code is: all of this file.
|
||||||
@@ -26,14 +26,22 @@
|
|||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
#ifndef BKE_SIMPLE_DEFORM_H
|
|
||||||
#define BKE_SIMPLE_DEFORM_H
|
#ifndef MOD_FLUIDSIM_UTIL_H
|
||||||
|
#define MOD_FLUIDSIM_UTIL_H
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
|
struct Scene;
|
||||||
|
struct FluidsimModifierData;
|
||||||
struct DerivedMesh;
|
struct DerivedMesh;
|
||||||
struct SimpleDeformModifierData;
|
|
||||||
|
|
||||||
void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
|
/* new fluid-modifier interface */
|
||||||
|
void fluidsim_init(struct FluidsimModifierData *fluidmd);
|
||||||
|
void fluidsim_free(struct FluidsimModifierData *fluidmd);
|
||||||
|
|
||||||
|
struct DerivedMesh *fluidsimModifier_do(struct FluidsimModifierData *fluidmd,
|
||||||
|
struct Scene *scene, struct Object *ob, struct DerivedMesh *dm,
|
||||||
|
int useRenderParams, int isFinalCalc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
320
source/blender/modifiers/intern/MOD_hook.c
Normal file
320
source/blender/modifiers/intern/MOD_hook.c
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
|
||||||
|
hmd->force= 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
HookModifierData *thmd = (HookModifierData*) target;
|
||||||
|
|
||||||
|
VECCOPY(thmd->cent, hmd->cent);
|
||||||
|
thmd->falloff = hmd->falloff;
|
||||||
|
thmd->force = hmd->force;
|
||||||
|
thmd->object = hmd->object;
|
||||||
|
thmd->totindex = hmd->totindex;
|
||||||
|
thmd->indexar = MEM_dupallocN(hmd->indexar);
|
||||||
|
memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
|
||||||
|
strncpy(thmd->name, hmd->name, 32);
|
||||||
|
strncpy(thmd->subtarget, hmd->subtarget, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(!hmd->indexar && hmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
|
||||||
|
if (hmd->indexar) MEM_freeN(hmd->indexar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
|
||||||
|
return !hmd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &hmd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
|
||||||
|
if (hmd->object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, hmd->object);
|
||||||
|
|
||||||
|
if (hmd->subtarget[0])
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, "Hook Modifier");
|
||||||
|
else
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
|
bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
|
||||||
|
float vec[3], mat[4][4], dmat[4][4];
|
||||||
|
int i;
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
/* get world-space matrix of target, corrected for the space the verts are in */
|
||||||
|
if (hmd->subtarget[0] && pchan) {
|
||||||
|
/* bone target if there's a matching pose-channel */
|
||||||
|
mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* just object target */
|
||||||
|
copy_m4_m4(dmat, hmd->object->obmat);
|
||||||
|
}
|
||||||
|
invert_m4_m4(ob->imat, ob->obmat);
|
||||||
|
mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv,
|
||||||
|
NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
/* vertex indices? */
|
||||||
|
if(hmd->indexar) {
|
||||||
|
for(i = 0; i < hmd->totindex; i++) {
|
||||||
|
int index = hmd->indexar[i];
|
||||||
|
|
||||||
|
/* This should always be true and I don't generally like
|
||||||
|
* "paranoid" style code like this, but old files can have
|
||||||
|
* indices that are out of range because old blender did
|
||||||
|
* not correct them on exit editmode. - zr
|
||||||
|
*/
|
||||||
|
if(index < numVerts) {
|
||||||
|
float *co = vertexCos[index];
|
||||||
|
float fac = hmd->force;
|
||||||
|
|
||||||
|
/* if DerivedMesh is present and has original index data,
|
||||||
|
* use it
|
||||||
|
*/
|
||||||
|
if(dm && dm->getVertDataArray(dm, CD_ORIGINDEX)) {
|
||||||
|
int j;
|
||||||
|
int orig_index;
|
||||||
|
for(j = 0; j < numVerts; ++j) {
|
||||||
|
fac = hmd->force;
|
||||||
|
orig_index = *(int *)dm->getVertData(dm, j,
|
||||||
|
CD_ORIGINDEX);
|
||||||
|
if(orig_index == index) {
|
||||||
|
co = vertexCos[j];
|
||||||
|
if(hmd->falloff != 0.0) {
|
||||||
|
float len = len_v3v3(co, hmd->cent);
|
||||||
|
if(len > hmd->falloff) fac = 0.0;
|
||||||
|
else if(len > 0.0)
|
||||||
|
fac *= sqrt(1.0 - len / hmd->falloff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fac != 0.0) {
|
||||||
|
mul_v3_m4v3(vec, mat, co);
|
||||||
|
interp_v3_v3v3(co, co, vec, fac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(hmd->falloff != 0.0) {
|
||||||
|
float len = len_v3v3(co, hmd->cent);
|
||||||
|
if(len > hmd->falloff) fac = 0.0;
|
||||||
|
else if(len > 0.0)
|
||||||
|
fac *= sqrt(1.0 - len / hmd->falloff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fac != 0.0) {
|
||||||
|
mul_v3_m4v3(vec, mat, co);
|
||||||
|
interp_v3_v3v3(co, co, vec, fac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(hmd->name[0]) { /* vertex group hook */
|
||||||
|
Mesh *me = ob->data;
|
||||||
|
int use_dverts = 0;
|
||||||
|
int maxVerts = 0;
|
||||||
|
int defgrp_index = defgroup_name_index(ob, hmd->name);
|
||||||
|
|
||||||
|
if(dm) {
|
||||||
|
if(dm->getVertData(dm, 0, CD_MDEFORMVERT)) {
|
||||||
|
maxVerts = dm->getNumVerts(dm);
|
||||||
|
use_dverts = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(me->dvert) {
|
||||||
|
maxVerts = me->totvert;
|
||||||
|
use_dverts = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defgrp_index >= 0 && use_dverts) {
|
||||||
|
MDeformVert *dvert = me->dvert;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for(i = 0; i < maxVerts; i++, dvert++) {
|
||||||
|
if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
|
||||||
|
for(j = 0; j < dvert->totweight; j++) {
|
||||||
|
if(dvert->dw[j].def_nr == defgrp_index) {
|
||||||
|
float fac = hmd->force*dvert->dw[j].weight;
|
||||||
|
float *co = vertexCos[i];
|
||||||
|
|
||||||
|
if(hmd->falloff != 0.0) {
|
||||||
|
float len = len_v3v3(co, hmd->cent);
|
||||||
|
if(len > hmd->falloff) fac = 0.0;
|
||||||
|
else if(len > 0.0)
|
||||||
|
fac *= sqrt(1.0 - len / hmd->falloff);
|
||||||
|
}
|
||||||
|
|
||||||
|
mul_v3_m4v3(vec, mat, co);
|
||||||
|
interp_v3_v3v3(co, co, vec, fac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
|
||||||
|
deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
|
||||||
|
|
||||||
|
if(!derivedData) dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Hook = {
|
||||||
|
/* name */ "Hook",
|
||||||
|
/* structName */ "HookModifierData",
|
||||||
|
/* structSize */ sizeof(HookModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
189
source/blender/modifiers/intern/MOD_lattice.c
Normal file
189
source/blender/modifiers/intern/MOD_lattice.c
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
LatticeModifierData *lmd = (LatticeModifierData*) md;
|
||||||
|
LatticeModifierData *tlmd = (LatticeModifierData*) target;
|
||||||
|
|
||||||
|
tlmd->object = lmd->object;
|
||||||
|
strncpy(tlmd->name, lmd->name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
LatticeModifierData *lmd = (LatticeModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(lmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int userRenderParams)
|
||||||
|
{
|
||||||
|
LatticeModifierData *lmd = (LatticeModifierData*) md;
|
||||||
|
|
||||||
|
return !lmd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
LatticeModifierData *lmd = (LatticeModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &lmd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
LatticeModifierData *lmd = (LatticeModifierData*) md;
|
||||||
|
|
||||||
|
if(lmd->object) {
|
||||||
|
DagNode *latNode = dag_get_node(forest, lmd->object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, latNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Lattice Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
LatticeModifierData *lmd = (LatticeModifierData*) md;
|
||||||
|
|
||||||
|
|
||||||
|
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
|
||||||
|
|
||||||
|
lattice_deform_verts(lmd->object, ob, derivedData,
|
||||||
|
vertexCos, numVerts, lmd->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
|
||||||
|
deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
|
||||||
|
|
||||||
|
if(!derivedData) dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Lattice = {
|
||||||
|
/* name */ "Lattice",
|
||||||
|
/* structName */ "LatticeModifierData",
|
||||||
|
/* structSize */ sizeof(LatticeModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
449
source/blender/modifiers/intern/MOD_mask.c
Normal file
449
source/blender/modifiers/intern/MOD_mask.c
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
MaskModifierData *mmd = (MaskModifierData*) md;
|
||||||
|
MaskModifierData *tmmd = (MaskModifierData*) target;
|
||||||
|
|
||||||
|
strcpy(tmmd->vgroup, mmd->vgroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
return (1 << CD_MDEFORMVERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
MaskModifierData *mmd = (MaskModifierData *)md;
|
||||||
|
walk(userData, ob, &mmd->ob_arm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
MaskModifierData *mmd = (MaskModifierData *)md;
|
||||||
|
|
||||||
|
if (mmd->ob_arm)
|
||||||
|
{
|
||||||
|
DagNode *armNode = dag_get_node(forest, mmd->ob_arm);
|
||||||
|
|
||||||
|
dag_add_relation(forest, armNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mask Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
||||||
|
DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
MaskModifierData *mmd= (MaskModifierData *)md;
|
||||||
|
DerivedMesh *dm= derivedData, *result= NULL;
|
||||||
|
GHash *vertHash=NULL, *edgeHash, *faceHash;
|
||||||
|
GHashIterator *hashIter;
|
||||||
|
MDeformVert *dvert= NULL;
|
||||||
|
int numFaces=0, numEdges=0, numVerts=0;
|
||||||
|
int maxVerts, maxEdges, maxFaces;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Overview of Method:
|
||||||
|
* 1. Get the vertices that are in the vertexgroup of interest
|
||||||
|
* 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
|
||||||
|
* 3. Make a new mesh containing only the mapping data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* get original number of verts, edges, and faces */
|
||||||
|
maxVerts= dm->getNumVerts(dm);
|
||||||
|
maxEdges= dm->getNumEdges(dm);
|
||||||
|
maxFaces= dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
/* check if we can just return the original mesh
|
||||||
|
* - must have verts and therefore verts assigned to vgroups to do anything useful
|
||||||
|
*/
|
||||||
|
if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
|
||||||
|
(maxVerts == 0) || (ob->defbase.first == NULL) )
|
||||||
|
{
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if mode is to use selected armature bones, aggregate the bone groups */
|
||||||
|
if (mmd->mode == MOD_MASK_MODE_ARM) /* --- using selected bones --- */
|
||||||
|
{
|
||||||
|
GHash *vgroupHash, *boneHash;
|
||||||
|
Object *oba= mmd->ob_arm;
|
||||||
|
bPoseChannel *pchan;
|
||||||
|
bDeformGroup *def;
|
||||||
|
|
||||||
|
/* check that there is armature object with bones to use, otherwise return original mesh */
|
||||||
|
if (ELEM(NULL, mmd->ob_arm, mmd->ob_arm->pose))
|
||||||
|
return derivedData;
|
||||||
|
|
||||||
|
/* hashes for finding mapping of:
|
||||||
|
* - vgroups to indicies -> vgroupHash (string, int)
|
||||||
|
* - bones to vgroup indices -> boneHash (index of vgroup, dummy)
|
||||||
|
*/
|
||||||
|
vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
|
||||||
|
boneHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
|
||||||
|
|
||||||
|
/* build mapping of names of vertex groups to indices */
|
||||||
|
for (i = 0, def = ob->defbase.first; def; def = def->next, i++)
|
||||||
|
BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
|
||||||
|
|
||||||
|
/* get selected-posechannel <-> vertexgroup index mapping */
|
||||||
|
for (pchan= oba->pose->chanbase.first; pchan; pchan= pchan->next)
|
||||||
|
{
|
||||||
|
/* check if bone is selected */
|
||||||
|
// TODO: include checks for visibility too?
|
||||||
|
// FIXME: the depsgraph needs extensions to make this work in realtime...
|
||||||
|
if ( (pchan->bone) && (pchan->bone->flag & BONE_SELECTED) )
|
||||||
|
{
|
||||||
|
/* check if hash has group for this bone */
|
||||||
|
if (BLI_ghash_haskey(vgroupHash, pchan->name))
|
||||||
|
{
|
||||||
|
int defgrp_index= GET_INT_FROM_POINTER(BLI_ghash_lookup(vgroupHash, pchan->name));
|
||||||
|
|
||||||
|
/* add index to hash (store under key only) */
|
||||||
|
BLI_ghash_insert(boneHash, SET_INT_IN_POINTER(defgrp_index), pchan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no bones selected, free hashes and return original mesh */
|
||||||
|
if (BLI_ghash_size(boneHash) == 0)
|
||||||
|
{
|
||||||
|
BLI_ghash_free(vgroupHash, NULL, NULL);
|
||||||
|
BLI_ghash_free(boneHash, NULL, NULL);
|
||||||
|
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* repeat the previous check, but for dverts */
|
||||||
|
dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
if (dvert == NULL)
|
||||||
|
{
|
||||||
|
BLI_ghash_free(vgroupHash, NULL, NULL);
|
||||||
|
BLI_ghash_free(boneHash, NULL, NULL);
|
||||||
|
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
|
||||||
|
vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
|
||||||
|
|
||||||
|
/* add vertices which exist in vertexgroups into vertHash for filtering */
|
||||||
|
for (i = 0; i < maxVerts; i++)
|
||||||
|
{
|
||||||
|
MDeformWeight *def_weight = NULL;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j= 0; j < dvert[i].totweight; j++)
|
||||||
|
{
|
||||||
|
if (BLI_ghash_haskey(boneHash, SET_INT_IN_POINTER(dvert[i].dw[j].def_nr)))
|
||||||
|
{
|
||||||
|
def_weight = &dvert[i].dw[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if include vert in vertHash */
|
||||||
|
if (mmd->flag & MOD_MASK_INV) {
|
||||||
|
/* if this vert is in the vgroup, don't include it in vertHash */
|
||||||
|
if (def_weight) continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* if this vert isn't in the vgroup, don't include it in vertHash */
|
||||||
|
if (!def_weight) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add to ghash for verts (numVerts acts as counter for mapping) */
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
|
||||||
|
numVerts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free temp hashes */
|
||||||
|
BLI_ghash_free(vgroupHash, NULL, NULL);
|
||||||
|
BLI_ghash_free(boneHash, NULL, NULL);
|
||||||
|
}
|
||||||
|
else /* --- Using Nominated VertexGroup only --- */
|
||||||
|
{
|
||||||
|
int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
|
||||||
|
|
||||||
|
/* get dverts */
|
||||||
|
if (defgrp_index >= 0)
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
/* if no vgroup (i.e. dverts) found, return the initial mesh */
|
||||||
|
if ((defgrp_index < 0) || (dvert == NULL))
|
||||||
|
return dm;
|
||||||
|
|
||||||
|
/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
|
||||||
|
vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
|
||||||
|
|
||||||
|
/* add vertices which exist in vertexgroup into ghash for filtering */
|
||||||
|
for (i = 0; i < maxVerts; i++)
|
||||||
|
{
|
||||||
|
MDeformWeight *def_weight = NULL;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j= 0; j < dvert[i].totweight; j++)
|
||||||
|
{
|
||||||
|
if (dvert[i].dw[j].def_nr == defgrp_index)
|
||||||
|
{
|
||||||
|
def_weight = &dvert[i].dw[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if include vert in vertHash */
|
||||||
|
if (mmd->flag & MOD_MASK_INV) {
|
||||||
|
/* if this vert is in the vgroup, don't include it in vertHash */
|
||||||
|
if (def_weight) continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* if this vert isn't in the vgroup, don't include it in vertHash */
|
||||||
|
if (!def_weight) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add to ghash for verts (numVerts acts as counter for mapping) */
|
||||||
|
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
|
||||||
|
numVerts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
|
||||||
|
edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
|
||||||
|
faceHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
|
||||||
|
|
||||||
|
/* loop over edges and faces, and do the same thing to
|
||||||
|
* ensure that they only reference existing verts
|
||||||
|
*/
|
||||||
|
for (i = 0; i < maxEdges; i++)
|
||||||
|
{
|
||||||
|
MEdge me;
|
||||||
|
dm->getEdge(dm, i, &me);
|
||||||
|
|
||||||
|
/* only add if both verts will be in new mesh */
|
||||||
|
if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
|
||||||
|
BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)) )
|
||||||
|
{
|
||||||
|
BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
|
||||||
|
numEdges++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < maxFaces; i++)
|
||||||
|
{
|
||||||
|
MFace mf;
|
||||||
|
dm->getFace(dm, i, &mf);
|
||||||
|
|
||||||
|
/* all verts must be available */
|
||||||
|
if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) &&
|
||||||
|
BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)) &&
|
||||||
|
BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)) &&
|
||||||
|
(mf.v4==0 || BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) )
|
||||||
|
{
|
||||||
|
BLI_ghash_insert(faceHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numFaces));
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* now we know the number of verts, edges and faces,
|
||||||
|
* we can create the new (reduced) mesh
|
||||||
|
*/
|
||||||
|
result = CDDM_from_template(dm, numVerts, numEdges, numFaces);
|
||||||
|
|
||||||
|
|
||||||
|
/* using ghash-iterators, map data into new mesh */
|
||||||
|
/* vertices */
|
||||||
|
for ( hashIter = BLI_ghashIterator_new(vertHash);
|
||||||
|
!BLI_ghashIterator_isDone(hashIter);
|
||||||
|
BLI_ghashIterator_step(hashIter) )
|
||||||
|
{
|
||||||
|
MVert source;
|
||||||
|
MVert *dest;
|
||||||
|
int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
|
||||||
|
int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
|
||||||
|
|
||||||
|
dm->getVert(dm, oldIndex, &source);
|
||||||
|
dest = CDDM_get_vert(result, newIndex);
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
|
||||||
|
*dest = source;
|
||||||
|
}
|
||||||
|
BLI_ghashIterator_free(hashIter);
|
||||||
|
|
||||||
|
/* edges */
|
||||||
|
for ( hashIter = BLI_ghashIterator_new(edgeHash);
|
||||||
|
!BLI_ghashIterator_isDone(hashIter);
|
||||||
|
BLI_ghashIterator_step(hashIter) )
|
||||||
|
{
|
||||||
|
MEdge source;
|
||||||
|
MEdge *dest;
|
||||||
|
int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
|
||||||
|
int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
|
||||||
|
|
||||||
|
dm->getEdge(dm, oldIndex, &source);
|
||||||
|
dest = CDDM_get_edge(result, newIndex);
|
||||||
|
|
||||||
|
source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
|
||||||
|
source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
|
||||||
|
|
||||||
|
DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
|
||||||
|
*dest = source;
|
||||||
|
}
|
||||||
|
BLI_ghashIterator_free(hashIter);
|
||||||
|
|
||||||
|
/* faces */
|
||||||
|
for ( hashIter = BLI_ghashIterator_new(faceHash);
|
||||||
|
!BLI_ghashIterator_isDone(hashIter);
|
||||||
|
BLI_ghashIterator_step(hashIter) )
|
||||||
|
{
|
||||||
|
MFace source;
|
||||||
|
MFace *dest;
|
||||||
|
int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
|
||||||
|
int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
|
||||||
|
int orig_v4;
|
||||||
|
|
||||||
|
dm->getFace(dm, oldIndex, &source);
|
||||||
|
dest = CDDM_get_face(result, newIndex);
|
||||||
|
|
||||||
|
orig_v4 = source.v4;
|
||||||
|
|
||||||
|
source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
|
||||||
|
source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
|
||||||
|
source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
|
||||||
|
if (source.v4)
|
||||||
|
source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, oldIndex, newIndex, 1);
|
||||||
|
*dest = source;
|
||||||
|
|
||||||
|
test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3));
|
||||||
|
}
|
||||||
|
BLI_ghashIterator_free(hashIter);
|
||||||
|
|
||||||
|
/* recalculate normals */
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
/* free hashes */
|
||||||
|
BLI_ghash_free(vertHash, NULL, NULL);
|
||||||
|
BLI_ghash_free(edgeHash, NULL, NULL);
|
||||||
|
BLI_ghash_free(faceHash, NULL, NULL);
|
||||||
|
|
||||||
|
/* return the new mesh */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Mask = {
|
||||||
|
/* name */ "Mask",
|
||||||
|
/* structName */ "MaskModifierData",
|
||||||
|
/* structSize */ sizeof(MaskModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
422
source/blender/modifiers/intern/MOD_meshdeform.c
Normal file
422
source/blender/modifiers/intern/MOD_meshdeform.c
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
|
||||||
|
mmd->gridsize= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
|
||||||
|
if(mmd->bindweights) MEM_freeN(mmd->bindweights);
|
||||||
|
if(mmd->bindcos) MEM_freeN(mmd->bindcos);
|
||||||
|
if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
|
||||||
|
if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
|
||||||
|
if(mmd->dynverts) MEM_freeN(mmd->dynverts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
MeshDeformModifierData *tmmd = (MeshDeformModifierData*) target;
|
||||||
|
|
||||||
|
tmmd->gridsize = mmd->gridsize;
|
||||||
|
tmmd->object = mmd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(mmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
|
||||||
|
return !mmd->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &mmd->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
|
||||||
|
if (mmd->object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, mmd->object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA|DAG_RL_OB_DATA|DAG_RL_DATA_OB|DAG_RL_OB_OB,
|
||||||
|
"Mesh Deform Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float *vec)
|
||||||
|
{
|
||||||
|
MDefCell *cell;
|
||||||
|
MDefInfluence *inf;
|
||||||
|
float gridvec[3], dvec[3], ivec[3], co[3], wx, wy, wz;
|
||||||
|
float weight, cageweight, totweight, *cageco;
|
||||||
|
int i, j, a, x, y, z, size;
|
||||||
|
|
||||||
|
co[0]= co[1]= co[2]= 0.0f;
|
||||||
|
totweight= 0.0f;
|
||||||
|
size= mmd->dyngridsize;
|
||||||
|
|
||||||
|
for(i=0; i<3; i++) {
|
||||||
|
gridvec[i]= (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth*0.5f)/mmd->dyncellwidth;
|
||||||
|
ivec[i]= (int)gridvec[i];
|
||||||
|
dvec[i]= gridvec[i] - ivec[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
if(i & 1) { x= ivec[0]+1; wx= dvec[0]; }
|
||||||
|
else { x= ivec[0]; wx= 1.0f-dvec[0]; }
|
||||||
|
|
||||||
|
if(i & 2) { y= ivec[1]+1; wy= dvec[1]; }
|
||||||
|
else { y= ivec[1]; wy= 1.0f-dvec[1]; }
|
||||||
|
|
||||||
|
if(i & 4) { z= ivec[2]+1; wz= dvec[2]; }
|
||||||
|
else { z= ivec[2]; wz= 1.0f-dvec[2]; }
|
||||||
|
|
||||||
|
CLAMP(x, 0, size-1);
|
||||||
|
CLAMP(y, 0, size-1);
|
||||||
|
CLAMP(z, 0, size-1);
|
||||||
|
|
||||||
|
a= x + y*size + z*size*size;
|
||||||
|
weight= wx*wy*wz;
|
||||||
|
|
||||||
|
cell= &mmd->dyngrid[a];
|
||||||
|
inf= mmd->dyninfluences + cell->offset;
|
||||||
|
for(j=0; j<cell->totinfluence; j++, inf++) {
|
||||||
|
cageco= dco[inf->vertex];
|
||||||
|
cageweight= weight*inf->weight;
|
||||||
|
co[0] += cageweight*cageco[0];
|
||||||
|
co[1] += cageweight*cageco[1];
|
||||||
|
co[2] += cageweight*cageco[2];
|
||||||
|
totweight += cageweight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VECCOPY(vec, co);
|
||||||
|
|
||||||
|
return totweight;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void meshdeformModifier_do(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *dm,
|
||||||
|
float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||||
|
Mesh *me= (mmd->object)? mmd->object->data: NULL;
|
||||||
|
EditMesh *em = (me)? BKE_mesh_get_editmesh(me): NULL;
|
||||||
|
DerivedMesh *tmpdm, *cagedm;
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
MDeformWeight *dw;
|
||||||
|
MVert *cagemvert;
|
||||||
|
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
|
||||||
|
float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
|
||||||
|
int a, b, totvert, totcagevert, defgrp_index;
|
||||||
|
|
||||||
|
if(!mmd->object || (!mmd->bindcos && !mmd->bindfunc))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* get cage derivedmesh */
|
||||||
|
if(em) {
|
||||||
|
tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0);
|
||||||
|
if(tmpdm)
|
||||||
|
tmpdm->release(tmpdm);
|
||||||
|
BKE_mesh_end_editmesh(me, em);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cagedm= mmd->object->derivedFinal;
|
||||||
|
|
||||||
|
/* if we don't have one computed, use derivedmesh from data
|
||||||
|
* without any modifiers */
|
||||||
|
if(!cagedm) {
|
||||||
|
cagedm= get_dm(md->scene, mmd->object, NULL, NULL, NULL, 0);
|
||||||
|
if(cagedm)
|
||||||
|
cagedm->needsFree= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!cagedm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* compute matrices to go in and out of cage object space */
|
||||||
|
invert_m4_m4(imat, mmd->object->obmat);
|
||||||
|
mul_m4_m4m4(cagemat, ob->obmat, imat);
|
||||||
|
mul_m4_m4m4(cmat, cagemat, mmd->bindmat);
|
||||||
|
invert_m4_m4(iobmat, cmat);
|
||||||
|
copy_m3_m4(icagemat, iobmat);
|
||||||
|
|
||||||
|
/* bind weights if needed */
|
||||||
|
if(!mmd->bindcos) {
|
||||||
|
static int recursive = 0;
|
||||||
|
|
||||||
|
/* progress bar redraw can make this recursive .. */
|
||||||
|
if(!recursive) {
|
||||||
|
recursive = 1;
|
||||||
|
mmd->bindfunc(md->scene, dm, mmd, (float*)vertexCos, numVerts, cagemat);
|
||||||
|
recursive = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify we have compatible weights */
|
||||||
|
totvert= numVerts;
|
||||||
|
totcagevert= cagedm->getNumVerts(cagedm);
|
||||||
|
|
||||||
|
if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindcos) {
|
||||||
|
cagedm->release(cagedm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup deformation data */
|
||||||
|
cagemvert= cagedm->getVertArray(cagedm);
|
||||||
|
weights= mmd->bindweights;
|
||||||
|
bindcos= (float(*)[3])mmd->bindcos;
|
||||||
|
|
||||||
|
dco= MEM_callocN(sizeof(*dco)*totcagevert, "MDefDco");
|
||||||
|
for(a=0; a<totcagevert; a++) {
|
||||||
|
/* get cage vertex in world space with binding transform */
|
||||||
|
VECCOPY(co, cagemvert[a].co);
|
||||||
|
|
||||||
|
if(G.rt != 527) {
|
||||||
|
mul_m4_v3(mmd->bindmat, co);
|
||||||
|
/* compute difference with world space bind coord */
|
||||||
|
VECSUB(dco[a], co, bindcos[a]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
VECCOPY(dco[a], co)
|
||||||
|
}
|
||||||
|
|
||||||
|
defgrp_index = defgroup_name_index(ob, mmd->defgrp_name);
|
||||||
|
|
||||||
|
if (defgrp_index >= 0)
|
||||||
|
dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
/* do deformation */
|
||||||
|
fac= 1.0f;
|
||||||
|
|
||||||
|
for(b=0; b<totvert; b++) {
|
||||||
|
if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
|
||||||
|
if(!mmd->dynverts[b])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(dvert) {
|
||||||
|
for(dw=NULL, a=0; a<dvert[b].totweight; a++) {
|
||||||
|
if(dvert[b].dw[a].def_nr == defgrp_index) {
|
||||||
|
dw = &dvert[b].dw[a];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mmd->flag & MOD_MDEF_INVERT_VGROUP) {
|
||||||
|
if(!dw) fac= 1.0f;
|
||||||
|
else if(dw->weight == 1.0f) continue;
|
||||||
|
else fac=1.0f-dw->weight;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!dw) continue;
|
||||||
|
else fac= dw->weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
|
||||||
|
/* transform coordinate into cage's local space */
|
||||||
|
VECCOPY(co, vertexCos[b]);
|
||||||
|
mul_m4_v3(cagemat, co);
|
||||||
|
totweight= meshdeform_dynamic_bind(mmd, dco, co);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
totweight= 0.0f;
|
||||||
|
co[0]= co[1]= co[2]= 0.0f;
|
||||||
|
|
||||||
|
for(a=0; a<totcagevert; a++) {
|
||||||
|
weight= weights[a + b*totcagevert];
|
||||||
|
co[0]+= weight*dco[a][0];
|
||||||
|
co[1]+= weight*dco[a][1];
|
||||||
|
co[2]+= weight*dco[a][2];
|
||||||
|
totweight += weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(totweight > 0.0f) {
|
||||||
|
mul_v3_fl(co, fac/totweight);
|
||||||
|
mul_m3_v3(icagemat, co);
|
||||||
|
if(G.rt != 527)
|
||||||
|
VECADD(vertexCos[b], vertexCos[b], co)
|
||||||
|
else
|
||||||
|
VECCOPY(vertexCos[b], co)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release cage derivedmesh */
|
||||||
|
MEM_freeN(dco);
|
||||||
|
cagedm->release(cagedm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);;
|
||||||
|
|
||||||
|
if(!dm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
|
||||||
|
|
||||||
|
meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm;
|
||||||
|
|
||||||
|
if(!derivedData && ob->type == OB_MESH)
|
||||||
|
dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
else
|
||||||
|
dm = derivedData;
|
||||||
|
|
||||||
|
meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_MeshDeform = {
|
||||||
|
/* name */ "MeshDeform",
|
||||||
|
/* structName */ "MeshDeformModifierData",
|
||||||
|
/* structSize */ sizeof(MeshDeformModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
392
source/blender/modifiers/intern/MOD_mirror.c
Normal file
392
source/blender/modifiers/intern/MOD_mirror.c
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
MirrorModifierData *mmd = (MirrorModifierData*) md;
|
||||||
|
|
||||||
|
mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
|
||||||
|
mmd->tolerance = 0.001;
|
||||||
|
mmd->mirror_ob = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
MirrorModifierData *mmd = (MirrorModifierData*) md;
|
||||||
|
MirrorModifierData *tmmd = (MirrorModifierData*) target;
|
||||||
|
|
||||||
|
tmmd->axis = mmd->axis;
|
||||||
|
tmmd->flag = mmd->flag;
|
||||||
|
tmmd->tolerance = mmd->tolerance;
|
||||||
|
tmmd->mirror_ob = mmd->mirror_ob;;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
MirrorModifierData *mmd = (MirrorModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &mmd->mirror_ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
|
||||||
|
Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
MirrorModifierData *mmd = (MirrorModifierData*) md;
|
||||||
|
|
||||||
|
if(mmd->mirror_ob) {
|
||||||
|
DagNode *latNode = dag_get_node(forest, mmd->mirror_ob);
|
||||||
|
|
||||||
|
dag_add_relation(forest, latNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mirror Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
|
||||||
|
Object *ob,
|
||||||
|
DerivedMesh *dm,
|
||||||
|
int initFlags,
|
||||||
|
int axis)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float tolerance = mmd->tolerance;
|
||||||
|
DerivedMesh *result;
|
||||||
|
int numVerts, numEdges, numFaces;
|
||||||
|
int maxVerts = dm->getNumVerts(dm);
|
||||||
|
int maxEdges = dm->getNumEdges(dm);
|
||||||
|
int maxFaces = dm->getNumFaces(dm);
|
||||||
|
int *flip_map= NULL;
|
||||||
|
int do_vgroup_mirr= (mmd->flag & MOD_MIR_VGROUP);
|
||||||
|
int (*indexMap)[2];
|
||||||
|
float mtx[4][4], imtx[4][4];
|
||||||
|
|
||||||
|
numVerts = numEdges = numFaces = 0;
|
||||||
|
|
||||||
|
indexMap = MEM_mallocN(sizeof(*indexMap) * maxVerts, "indexmap");
|
||||||
|
|
||||||
|
result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2);
|
||||||
|
|
||||||
|
|
||||||
|
if (do_vgroup_mirr) {
|
||||||
|
flip_map= defgroup_flip_map(ob, 0);
|
||||||
|
if(flip_map == NULL)
|
||||||
|
do_vgroup_mirr= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmd->mirror_ob) {
|
||||||
|
float obinv[4][4];
|
||||||
|
|
||||||
|
invert_m4_m4(obinv, mmd->mirror_ob->obmat);
|
||||||
|
mul_m4_m4m4(mtx, ob->obmat, obinv);
|
||||||
|
invert_m4_m4(imtx, mtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < maxVerts; i++) {
|
||||||
|
MVert inMV;
|
||||||
|
MVert *mv = CDDM_get_vert(result, numVerts);
|
||||||
|
int isShared;
|
||||||
|
float co[3];
|
||||||
|
|
||||||
|
dm->getVert(dm, i, &inMV);
|
||||||
|
|
||||||
|
copy_v3_v3(co, inMV.co);
|
||||||
|
|
||||||
|
if (mmd->mirror_ob) {
|
||||||
|
mul_v3_m4v3(co, mtx, co);
|
||||||
|
}
|
||||||
|
isShared = ABS(co[axis])<=tolerance;
|
||||||
|
|
||||||
|
/* Because the topology result (# of vertices) must be the same if
|
||||||
|
* the mesh data is overridden by vertex cos, have to calc sharedness
|
||||||
|
* based on original coordinates. This is why we test before copy.
|
||||||
|
*/
|
||||||
|
DM_copy_vert_data(dm, result, i, numVerts, 1);
|
||||||
|
*mv = inMV;
|
||||||
|
numVerts++;
|
||||||
|
|
||||||
|
indexMap[i][0] = numVerts - 1;
|
||||||
|
indexMap[i][1] = !isShared;
|
||||||
|
|
||||||
|
if(isShared) {
|
||||||
|
co[axis] = 0;
|
||||||
|
if (mmd->mirror_ob) {
|
||||||
|
mul_v3_m4v3(co, imtx, co);
|
||||||
|
}
|
||||||
|
copy_v3_v3(mv->co, co);
|
||||||
|
|
||||||
|
mv->flag |= ME_VERT_MERGED;
|
||||||
|
} else {
|
||||||
|
MVert *mv2 = CDDM_get_vert(result, numVerts);
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm, result, i, numVerts, 1);
|
||||||
|
*mv2 = *mv;
|
||||||
|
|
||||||
|
co[axis] = -co[axis];
|
||||||
|
if (mmd->mirror_ob) {
|
||||||
|
mul_v3_m4v3(co, imtx, co);
|
||||||
|
}
|
||||||
|
copy_v3_v3(mv2->co, co);
|
||||||
|
|
||||||
|
if (do_vgroup_mirr) {
|
||||||
|
MDeformVert *dvert= DM_get_vert_data(result, numVerts, CD_MDEFORMVERT);
|
||||||
|
if(dvert) {
|
||||||
|
defvert_flip(dvert, flip_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
numVerts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < maxEdges; i++) {
|
||||||
|
MEdge inMED;
|
||||||
|
MEdge *med = CDDM_get_edge(result, numEdges);
|
||||||
|
|
||||||
|
dm->getEdge(dm, i, &inMED);
|
||||||
|
|
||||||
|
DM_copy_edge_data(dm, result, i, numEdges, 1);
|
||||||
|
*med = inMED;
|
||||||
|
numEdges++;
|
||||||
|
|
||||||
|
med->v1 = indexMap[inMED.v1][0];
|
||||||
|
med->v2 = indexMap[inMED.v2][0];
|
||||||
|
if(initFlags)
|
||||||
|
med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
|
||||||
|
|
||||||
|
if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) {
|
||||||
|
MEdge *med2 = CDDM_get_edge(result, numEdges);
|
||||||
|
|
||||||
|
DM_copy_edge_data(dm, result, i, numEdges, 1);
|
||||||
|
*med2 = *med;
|
||||||
|
numEdges++;
|
||||||
|
|
||||||
|
med2->v1 += indexMap[inMED.v1][1];
|
||||||
|
med2->v2 += indexMap[inMED.v2][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < maxFaces; i++) {
|
||||||
|
MFace inMF;
|
||||||
|
MFace *mf = CDDM_get_face(result, numFaces);
|
||||||
|
|
||||||
|
dm->getFace(dm, i, &inMF);
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, i, numFaces, 1);
|
||||||
|
*mf = inMF;
|
||||||
|
numFaces++;
|
||||||
|
|
||||||
|
mf->v1 = indexMap[inMF.v1][0];
|
||||||
|
mf->v2 = indexMap[inMF.v2][0];
|
||||||
|
mf->v3 = indexMap[inMF.v3][0];
|
||||||
|
mf->v4 = indexMap[inMF.v4][0];
|
||||||
|
|
||||||
|
if(indexMap[inMF.v1][1]
|
||||||
|
|| indexMap[inMF.v2][1]
|
||||||
|
|| indexMap[inMF.v3][1]
|
||||||
|
|| (mf->v4 && indexMap[inMF.v4][1])) {
|
||||||
|
MFace *mf2 = CDDM_get_face(result, numFaces);
|
||||||
|
static int corner_indices[4] = {2, 1, 0, 3};
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, i, numFaces, 1);
|
||||||
|
*mf2 = *mf;
|
||||||
|
|
||||||
|
mf2->v1 += indexMap[inMF.v1][1];
|
||||||
|
mf2->v2 += indexMap[inMF.v2][1];
|
||||||
|
mf2->v3 += indexMap[inMF.v3][1];
|
||||||
|
if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1];
|
||||||
|
|
||||||
|
/* mirror UVs if enabled */
|
||||||
|
if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) {
|
||||||
|
MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE);
|
||||||
|
if(tf) {
|
||||||
|
int j;
|
||||||
|
for(j = 0; j < 4; ++j) {
|
||||||
|
if(mmd->flag & MOD_MIR_MIRROR_U)
|
||||||
|
tf->uv[j][0] = 1.0f - tf->uv[j][0];
|
||||||
|
if(mmd->flag & MOD_MIR_MIRROR_V)
|
||||||
|
tf->uv[j][1] = 1.0f - tf->uv[j][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flip face normal */
|
||||||
|
SWAP(int, mf2->v1, mf2->v3);
|
||||||
|
DM_swap_face_data(result, numFaces, corner_indices);
|
||||||
|
|
||||||
|
test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
|
||||||
|
numFaces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flip_map) MEM_freeN(flip_map);
|
||||||
|
|
||||||
|
MEM_freeN(indexMap);
|
||||||
|
|
||||||
|
CDDM_lower_num_verts(result, numVerts);
|
||||||
|
CDDM_lower_num_edges(result, numEdges);
|
||||||
|
CDDM_lower_num_faces(result, numFaces);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
|
||||||
|
Object *ob, DerivedMesh *dm,
|
||||||
|
int initFlags)
|
||||||
|
{
|
||||||
|
DerivedMesh *result = dm;
|
||||||
|
|
||||||
|
/* check which axes have been toggled and mirror accordingly */
|
||||||
|
if(mmd->flag & MOD_MIR_AXIS_X) {
|
||||||
|
result = doMirrorOnAxis(mmd, ob, result, initFlags, 0);
|
||||||
|
}
|
||||||
|
if(mmd->flag & MOD_MIR_AXIS_Y) {
|
||||||
|
DerivedMesh *tmp = result;
|
||||||
|
result = doMirrorOnAxis(mmd, ob, result, initFlags, 1);
|
||||||
|
if(tmp != dm) tmp->release(tmp); /* free intermediate results */
|
||||||
|
}
|
||||||
|
if(mmd->flag & MOD_MIR_AXIS_Z) {
|
||||||
|
DerivedMesh *tmp = result;
|
||||||
|
result = doMirrorOnAxis(mmd, ob, result, initFlags, 2);
|
||||||
|
if(tmp != dm) tmp->release(tmp); /* free intermediate results */
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *result;
|
||||||
|
MirrorModifierData *mmd = (MirrorModifierData*) md;
|
||||||
|
|
||||||
|
result = mirrorModifier__doMirror(mmd, ob, derivedData, 0);
|
||||||
|
|
||||||
|
if(result != derivedData)
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Mirror = {
|
||||||
|
/* name */ "Mirror",
|
||||||
|
/* structName */ "MirrorModifierData",
|
||||||
|
/* structSize */ sizeof(MirrorModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_SupportsMapping
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode
|
||||||
|
| eModifierTypeFlag_AcceptsCVs,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
157
source/blender/modifiers/intern/MOD_multires.c
Normal file
157
source/blender/modifiers/intern/MOD_multires.c
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
MultiresModifierData *mmd = (MultiresModifierData*)md;
|
||||||
|
|
||||||
|
mmd->lvl = 0;
|
||||||
|
mmd->sculptlvl = 0;
|
||||||
|
mmd->renderlvl = 0;
|
||||||
|
mmd->totlvl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
MultiresModifierData *mmd = (MultiresModifierData*) md;
|
||||||
|
MultiresModifierData *tmmd = (MultiresModifierData*) target;
|
||||||
|
|
||||||
|
tmmd->lvl = mmd->lvl;
|
||||||
|
tmmd->sculptlvl = mmd->sculptlvl;
|
||||||
|
tmmd->renderlvl = mmd->renderlvl;
|
||||||
|
tmmd->totlvl = mmd->totlvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
MultiresModifierData *mmd = (MultiresModifierData*)md;
|
||||||
|
DerivedMesh *result;
|
||||||
|
|
||||||
|
result = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
|
||||||
|
|
||||||
|
if(result == dm)
|
||||||
|
return dm;
|
||||||
|
|
||||||
|
if(useRenderParams || !isFinalCalc) {
|
||||||
|
DerivedMesh *cddm= CDDM_copy(result);
|
||||||
|
result->release(result);
|
||||||
|
result= cddm;
|
||||||
|
}
|
||||||
|
else if((ob->mode & OB_MODE_SCULPT) && ob->sculpt) {
|
||||||
|
/* would be created on the fly too, just nicer this
|
||||||
|
way on first stroke after e.g. switching levels */
|
||||||
|
ob->sculpt->pbvh= result->getPBVH(ob, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Multires = {
|
||||||
|
/* name */ "Multires",
|
||||||
|
/* structName */ "MultiresModifierData",
|
||||||
|
/* structSize */ sizeof(MultiresModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_RequiresOriginalData,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
70
source/blender/modifiers/intern/MOD_none.c
Normal file
70
source/blender/modifiers/intern/MOD_none.c
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful;
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation;
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
/* We only need to define isDisabled; because it always returns 1,
|
||||||
|
* no other functions will be called
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int userRenderParams)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_None = {
|
||||||
|
/* name */ "None",
|
||||||
|
/* structName */ "ModifierData",
|
||||||
|
/* structSize */ sizeof(ModifierData),
|
||||||
|
/* type */ eModifierType_None,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_AcceptsCVs,
|
||||||
|
|
||||||
|
/* copyData */ 0,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
374
source/blender/modifiers/intern/MOD_particleinstance.c
Normal file
374
source/blender/modifiers/intern/MOD_particleinstance.c
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
|
||||||
|
|
||||||
|
pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn|
|
||||||
|
eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead;
|
||||||
|
pimd->psys = 1;
|
||||||
|
pimd->position = 1.0f;
|
||||||
|
pimd->axis = 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
|
||||||
|
ParticleInstanceModifierData *tpimd= (ParticleInstanceModifierData*) target;
|
||||||
|
|
||||||
|
tpimd->ob = pimd->ob;
|
||||||
|
tpimd->psys = pimd->psys;
|
||||||
|
tpimd->flag = pimd->flag;
|
||||||
|
tpimd->axis = pimd->axis;
|
||||||
|
tpimd->position = pimd->position;
|
||||||
|
tpimd->random_position = pimd->random_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest,
|
||||||
|
Scene *scene,Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
|
||||||
|
|
||||||
|
if (pimd->ob) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, pimd->ob);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
|
||||||
|
"Particle Instance Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(ModifierData *md, Object *ob,
|
||||||
|
ObjectWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &pimd->ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh * applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData, *result;
|
||||||
|
ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
|
||||||
|
ParticleSimulationData sim;
|
||||||
|
ParticleSystem * psys=0;
|
||||||
|
ParticleData *pa=0, *pars=0;
|
||||||
|
MFace *mface, *orig_mface;
|
||||||
|
MVert *mvert, *orig_mvert;
|
||||||
|
int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
|
||||||
|
short track=ob->trackflag%3, trackneg, axis = pimd->axis;
|
||||||
|
float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
|
||||||
|
float *size=NULL;
|
||||||
|
|
||||||
|
trackneg=((ob->trackflag>2)?1:0);
|
||||||
|
|
||||||
|
if(pimd->ob==ob){
|
||||||
|
pimd->ob=0;
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pimd->ob){
|
||||||
|
psys = BLI_findlink(&pimd->ob->particlesystem,pimd->psys-1);
|
||||||
|
if(psys==0 || psys->totpart==0)
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
|
else return derivedData;
|
||||||
|
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_Parents)
|
||||||
|
totpart+=psys->totpart;
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_Children){
|
||||||
|
if(totpart==0)
|
||||||
|
first_particle=psys->totpart;
|
||||||
|
totpart+=psys->totchild;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(totpart==0)
|
||||||
|
return derivedData;
|
||||||
|
|
||||||
|
sim.scene = md->scene;
|
||||||
|
sim.ob = pimd->ob;
|
||||||
|
sim.psys = psys;
|
||||||
|
sim.psmd = psys_get_modifier(pimd->ob, psys);
|
||||||
|
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_UseSize) {
|
||||||
|
int p;
|
||||||
|
float *si;
|
||||||
|
si = size = MEM_callocN(totpart * sizeof(float), "particle size array");
|
||||||
|
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_Parents) {
|
||||||
|
for(p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++)
|
||||||
|
*si = pa->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_Children) {
|
||||||
|
ChildParticle *cpa = psys->child;
|
||||||
|
|
||||||
|
for(p=0; p<psys->totchild; p++, cpa++, si++) {
|
||||||
|
*si = psys_get_child_size(psys, cpa, 0.0f, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pars=psys->particles;
|
||||||
|
|
||||||
|
totvert=dm->getNumVerts(dm);
|
||||||
|
totface=dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
maxvert=totvert*totpart;
|
||||||
|
maxface=totface*totpart;
|
||||||
|
|
||||||
|
psys->lattice=psys_get_lattice(&sim);
|
||||||
|
|
||||||
|
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){
|
||||||
|
|
||||||
|
float min_r[3], max_r[3];
|
||||||
|
INIT_MINMAX(min_r, max_r);
|
||||||
|
dm->getMinMax(dm, min_r, max_r);
|
||||||
|
min_co=min_r[track];
|
||||||
|
max_co=max_r[track];
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface);
|
||||||
|
|
||||||
|
mvert=result->getVertArray(result);
|
||||||
|
orig_mvert=dm->getVertArray(dm);
|
||||||
|
|
||||||
|
for(i=0; i<maxvert; i++){
|
||||||
|
MVert *inMV;
|
||||||
|
MVert *mv = mvert + i;
|
||||||
|
ParticleKey state;
|
||||||
|
|
||||||
|
inMV = orig_mvert + i%totvert;
|
||||||
|
DM_copy_vert_data(dm, result, i%totvert, i, 1);
|
||||||
|
*mv = *inMV;
|
||||||
|
|
||||||
|
/*change orientation based on object trackflag*/
|
||||||
|
VECCOPY(temp_co,mv->co);
|
||||||
|
mv->co[axis]=temp_co[track];
|
||||||
|
mv->co[(axis+1)%3]=temp_co[(track+1)%3];
|
||||||
|
mv->co[(axis+2)%3]=temp_co[(track+2)%3];
|
||||||
|
|
||||||
|
if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){
|
||||||
|
float ran = 0.0f;
|
||||||
|
if(pimd->random_position != 0.0f) {
|
||||||
|
BLI_srandom(psys->seed + (i/totvert)%totpart);
|
||||||
|
ran = pimd->random_position * BLI_frand();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_KeepShape) {
|
||||||
|
state.time = pimd->position * (1.0f - ran);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran);
|
||||||
|
|
||||||
|
if(trackneg)
|
||||||
|
state.time=1.0f-state.time;
|
||||||
|
|
||||||
|
mv->co[axis] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);
|
||||||
|
|
||||||
|
normalize_v3(state.vel);
|
||||||
|
|
||||||
|
/* TODO: incremental rotations somehow */
|
||||||
|
if(state.vel[axis] < -0.9999 || state.vel[axis] > 0.9999) {
|
||||||
|
state.rot[0] = 1;
|
||||||
|
state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float temp[3] = {0.0f,0.0f,0.0f};
|
||||||
|
temp[axis] = 1.0f;
|
||||||
|
|
||||||
|
cross_v3_v3v3(cross, temp, state.vel);
|
||||||
|
|
||||||
|
/* state.vel[axis] is the only component surviving from a dot product with the axis */
|
||||||
|
axis_angle_to_quat(state.rot,cross,saacos(state.vel[axis]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
state.time=-1.0;
|
||||||
|
psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mul_qt_v3(state.rot,mv->co);
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_UseSize)
|
||||||
|
mul_v3_fl(mv->co, size[i/totvert]);
|
||||||
|
VECADD(mv->co,mv->co,state.co);
|
||||||
|
}
|
||||||
|
|
||||||
|
mface=result->getFaceArray(result);
|
||||||
|
orig_mface=dm->getFaceArray(dm);
|
||||||
|
|
||||||
|
for(i=0; i<maxface; i++){
|
||||||
|
MFace *inMF;
|
||||||
|
MFace *mf = mface + i;
|
||||||
|
|
||||||
|
if(pimd->flag & eParticleInstanceFlag_Parents){
|
||||||
|
if(i/totface>=psys->totpart){
|
||||||
|
if(psys->part->childtype==PART_CHILD_PARTICLES)
|
||||||
|
pa=psys->particles+(psys->child+i/totface-psys->totpart)->parent;
|
||||||
|
else
|
||||||
|
pa=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pa=pars+i/totface;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(psys->part->childtype==PART_CHILD_PARTICLES)
|
||||||
|
pa=psys->particles+(psys->child+i/totface)->parent;
|
||||||
|
else
|
||||||
|
pa=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pa){
|
||||||
|
if(pa->alive==PARS_UNBORN && (pimd->flag&eParticleInstanceFlag_Unborn)==0) continue;
|
||||||
|
if(pa->alive==PARS_ALIVE && (pimd->flag&eParticleInstanceFlag_Alive)==0) continue;
|
||||||
|
if(pa->alive==PARS_DEAD && (pimd->flag&eParticleInstanceFlag_Dead)==0) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
inMF = orig_mface + i%totface;
|
||||||
|
DM_copy_face_data(dm, result, i%totface, i, 1);
|
||||||
|
*mf = *inMF;
|
||||||
|
|
||||||
|
mf->v1+=(i/totface)*totvert;
|
||||||
|
mf->v2+=(i/totface)*totvert;
|
||||||
|
mf->v3+=(i/totface)*totvert;
|
||||||
|
if(mf->v4)
|
||||||
|
mf->v4+=(i/totface)*totvert;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDDM_calc_edges(result);
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
|
||||||
|
if(psys->lattice){
|
||||||
|
end_latt_deform(psys->lattice);
|
||||||
|
psys->lattice= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(size)
|
||||||
|
MEM_freeN(size);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_ParticleInstance = {
|
||||||
|
/* name */ "ParticleInstance",
|
||||||
|
/* structName */ "ParticleInstanceModifierData",
|
||||||
|
/* structSize */ sizeof(ParticleInstanceModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh |
|
||||||
|
eModifierTypeFlag_SupportsMapping |
|
||||||
|
eModifierTypeFlag_SupportsEditmode |
|
||||||
|
eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
273
source/blender/modifiers/intern/MOD_particlesystem.c
Normal file
273
source/blender/modifiers/intern/MOD_particlesystem.c
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
|
||||||
|
psmd->psys= 0;
|
||||||
|
psmd->dm=0;
|
||||||
|
psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0;
|
||||||
|
}
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
|
||||||
|
|
||||||
|
if(psmd->dm){
|
||||||
|
psmd->dm->needsFree = 1;
|
||||||
|
psmd->dm->release(psmd->dm);
|
||||||
|
psmd->dm=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ED_object_modifier_remove may have freed this first before calling
|
||||||
|
* modifier_free (which calls this function) */
|
||||||
|
if(psmd->psys)
|
||||||
|
psmd->psys->flag |= PSYS_DELETE;
|
||||||
|
}
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
|
||||||
|
ParticleSystemModifierData *tpsmd= (ParticleSystemModifierData*) target;
|
||||||
|
|
||||||
|
tpsmd->dm = 0;
|
||||||
|
tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
|
||||||
|
//tpsmd->facepa = 0;
|
||||||
|
tpsmd->flag = psmd->flag;
|
||||||
|
/* need to keep this to recognise a bit later in copy_object */
|
||||||
|
tpsmd->psys = psmd->psys;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
Material *ma;
|
||||||
|
MTex *mtex;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(!psmd->psys->part)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ma= give_current_material(ob, psmd->psys->part->omat);
|
||||||
|
if(ma) {
|
||||||
|
for(i=0; i<MAX_MTEX; i++) {
|
||||||
|
mtex=ma->mtex[i];
|
||||||
|
if(mtex && (ma->septex & (1<<i))==0)
|
||||||
|
if(mtex->pmapto && (mtex->texco & TEXCO_UV))
|
||||||
|
dataMask |= (1 << CD_MTFACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(psmd->psys->part->tanfac!=0.0)
|
||||||
|
dataMask |= (1 << CD_MTFACE);
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
for(i=0; i<PSYS_TOT_VG; i++){
|
||||||
|
if(psmd->psys->vgroup[i]){
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* particles only need this if they are after a non deform modifier, and
|
||||||
|
* the modifier stack will only create them in that case. */
|
||||||
|
dataMask |= CD_MASK_ORIGSPACE;
|
||||||
|
|
||||||
|
dataMask |= CD_MASK_ORCO;
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* saves the current emitter state for a particle system and calculates particles */
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
|
||||||
|
ParticleSystem * psys=0;
|
||||||
|
int needsFree=0;
|
||||||
|
|
||||||
|
if(ob->particlesystem.first)
|
||||||
|
psys=psmd->psys;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!psys_check_enabled(ob, psys))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(dm==0) {
|
||||||
|
dm= get_dm(md->scene, ob, NULL, NULL, vertexCos, 1);
|
||||||
|
|
||||||
|
if(!dm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
needsFree= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear old dm */
|
||||||
|
if(psmd->dm){
|
||||||
|
psmd->dm->needsFree = 1;
|
||||||
|
psmd->dm->release(psmd->dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make new dm */
|
||||||
|
psmd->dm=CDDM_copy(dm);
|
||||||
|
CDDM_apply_vert_coords(psmd->dm, vertexCos);
|
||||||
|
CDDM_calc_normals(psmd->dm);
|
||||||
|
|
||||||
|
if(needsFree){
|
||||||
|
dm->needsFree = 1;
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* protect dm */
|
||||||
|
psmd->dm->needsFree = 0;
|
||||||
|
|
||||||
|
/* report change in mesh structure */
|
||||||
|
if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert ||
|
||||||
|
psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge ||
|
||||||
|
psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){
|
||||||
|
/* in file read dm hasn't really changed but just wasn't saved in file */
|
||||||
|
|
||||||
|
psys->recalc |= PSYS_RECALC_RESET;
|
||||||
|
psmd->flag |= eParticleSystemFlag_DM_changed;
|
||||||
|
|
||||||
|
psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
|
||||||
|
psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm);
|
||||||
|
psmd->totdmface= psmd->dm->getNumFaces(psmd->dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(psys) {
|
||||||
|
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||||
|
particle_system_update(md->scene, ob, psys);
|
||||||
|
psmd->flag |= eParticleSystemFlag_psys_updated;
|
||||||
|
psmd->flag &= ~eParticleSystemFlag_DM_changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disabled particles in editmode for now, until support for proper derivedmesh
|
||||||
|
* updates is coded */
|
||||||
|
#if 0
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
|
||||||
|
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
|
||||||
|
|
||||||
|
deformVerts(md, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(!derivedData) dm->release(dm);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_ParticleSystem = {
|
||||||
|
/* name */ "ParticleSystem",
|
||||||
|
/* structName */ "ParticleSystemModifierData",
|
||||||
|
/* structSize */ sizeof(ParticleSystemModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh |
|
||||||
|
eModifierTypeFlag_SupportsMapping |
|
||||||
|
eModifierTypeFlag_UsesPointCache /* |
|
||||||
|
eModifierTypeFlag_SupportsEditmode |
|
||||||
|
eModifierTypeFlag_EnableInEditmode */,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ 0 /* deformVertsEM */ ,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
925
source/blender/modifiers/intern/MOD_screw.c
Normal file
925
source/blender/modifiers/intern/MOD_screw.c
Normal file
@@ -0,0 +1,925 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
/* Screw modifier: revolves the edges about an axis
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* used for gathering edge connectivity */
|
||||||
|
typedef struct ScrewVertConnect {
|
||||||
|
float dist; /* distance from the center axis */
|
||||||
|
float co[3]; /* loaction relative to the transformed axis */
|
||||||
|
float no[3]; /* calc normal of the vertex */
|
||||||
|
int v[2]; /* 2 verts on either side of this one */
|
||||||
|
MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */
|
||||||
|
char flag;
|
||||||
|
} ScrewVertConnect;
|
||||||
|
|
||||||
|
typedef struct ScrewVertIter {
|
||||||
|
ScrewVertConnect * v_array;
|
||||||
|
ScrewVertConnect * v_poin;
|
||||||
|
int v;
|
||||||
|
int v_other;
|
||||||
|
MEdge *e;
|
||||||
|
} ScrewVertIter;
|
||||||
|
|
||||||
|
#define ScrewVertIter_INIT(iter, array, v_init, dir)\
|
||||||
|
iter.v_array = array;\
|
||||||
|
iter.v = v_init;\
|
||||||
|
if (v_init>=0) {\
|
||||||
|
iter.v_poin = &array[v_init];\
|
||||||
|
iter.v_other = iter.v_poin->v[dir];\
|
||||||
|
if (dir)\
|
||||||
|
iter.e = iter.v_poin->e[0];\
|
||||||
|
else\
|
||||||
|
iter.e = iter.v_poin->e[1];\
|
||||||
|
} else {\
|
||||||
|
iter.v_poin= NULL;\
|
||||||
|
iter.e= NULL;\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ScrewVertIter_NEXT(iter)\
|
||||||
|
if (iter.v_poin->v[0] == iter.v_other) {\
|
||||||
|
iter.v_other= iter.v;\
|
||||||
|
iter.v= iter.v_poin->v[1];\
|
||||||
|
} else if (iter.v_poin->v[1] == iter.v_other) {\
|
||||||
|
iter.v_other= iter.v;\
|
||||||
|
iter.v= iter.v_poin->v[0];\
|
||||||
|
}\
|
||||||
|
if (iter.v >=0) {\
|
||||||
|
iter.v_poin= &iter.v_array[iter.v];\
|
||||||
|
if ( iter.v_poin->e[0] != iter.e ) iter.e= iter.v_poin->e[0];\
|
||||||
|
else iter.e= iter.v_poin->e[1];\
|
||||||
|
} else {\
|
||||||
|
iter.e= NULL;\
|
||||||
|
iter.v_poin= NULL;\
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ScrewModifierData *ltmd= (ScrewModifierData*) md;
|
||||||
|
ltmd->ob_axis= NULL;
|
||||||
|
ltmd->angle= M_PI * 2.0;
|
||||||
|
ltmd->axis= 2;
|
||||||
|
ltmd->flag= 0;
|
||||||
|
ltmd->steps= 16;
|
||||||
|
ltmd->render_steps= 16;
|
||||||
|
ltmd->iter= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ScrewModifierData *sltmd= (ScrewModifierData*) md;
|
||||||
|
ScrewModifierData *tltmd= (ScrewModifierData*) target;
|
||||||
|
|
||||||
|
tltmd->ob_axis= sltmd->ob_axis;
|
||||||
|
tltmd->angle= sltmd->angle;
|
||||||
|
tltmd->axis= sltmd->axis;
|
||||||
|
tltmd->flag= sltmd->flag;
|
||||||
|
tltmd->steps= sltmd->steps;
|
||||||
|
tltmd->render_steps= sltmd->render_steps;
|
||||||
|
tltmd->screw_ofs= sltmd->screw_ofs;
|
||||||
|
tltmd->iter= sltmd->iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
||||||
|
DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= derivedData;
|
||||||
|
DerivedMesh *result;
|
||||||
|
ScrewModifierData *ltmd= (ScrewModifierData*) md;
|
||||||
|
|
||||||
|
int *origindex;
|
||||||
|
int mface_index=0;
|
||||||
|
int i, j;
|
||||||
|
int i1,i2;
|
||||||
|
int steps= ltmd->steps;
|
||||||
|
int maxVerts=0, maxEdges=0, maxFaces=0;
|
||||||
|
int totvert= dm->getNumVerts(dm);
|
||||||
|
int totedge= dm->getNumEdges(dm);
|
||||||
|
|
||||||
|
char axis_char, close;
|
||||||
|
float angle= ltmd->angle;
|
||||||
|
float screw_ofs= ltmd->screw_ofs;
|
||||||
|
float axis_vec[3]= {0.0f, 0.0f, 0.0f};
|
||||||
|
float tmp_vec1[3], tmp_vec2[3];
|
||||||
|
float mat3[3][3];
|
||||||
|
float mtx_tx[4][4]; /* transform the coords by an object relative to this objects transformation */
|
||||||
|
float mtx_tx_inv[4][4]; /* inverted */
|
||||||
|
float mtx_tmp_a[4][4];
|
||||||
|
|
||||||
|
int vc_tot_linked= 0;
|
||||||
|
short other_axis_1, other_axis_2;
|
||||||
|
float *tmpf1, *tmpf2;
|
||||||
|
|
||||||
|
MFace *mface_new, *mf_new;
|
||||||
|
MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new;
|
||||||
|
MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base;
|
||||||
|
|
||||||
|
ScrewVertConnect *vc, *vc_tmp, *vert_connect= NULL;
|
||||||
|
|
||||||
|
float mat[4][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, 0.0f, 1.0f}};
|
||||||
|
|
||||||
|
/* dont do anything? */
|
||||||
|
if (!totvert)
|
||||||
|
return CDDM_from_template(dm, 0, 0, 0);
|
||||||
|
|
||||||
|
steps= useRenderParams ? ltmd->render_steps : ltmd->steps;
|
||||||
|
|
||||||
|
switch(ltmd->axis) {
|
||||||
|
case 0:
|
||||||
|
other_axis_1=1;
|
||||||
|
other_axis_2=2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
other_axis_1=0;
|
||||||
|
other_axis_2=2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
other_axis_1=0;
|
||||||
|
other_axis_2=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
axis_vec[ltmd->axis]= 1.0f;
|
||||||
|
|
||||||
|
if (ltmd->ob_axis) {
|
||||||
|
float mtx3_tx[3][3];
|
||||||
|
/* calc the matrix relative to the axis object */
|
||||||
|
invert_m4_m4(mtx_tmp_a, ob->obmat);
|
||||||
|
copy_m4_m4(mtx_tx_inv, ltmd->ob_axis->obmat);
|
||||||
|
mul_m4_m4m4(mtx_tx, mtx_tx_inv, mtx_tmp_a);
|
||||||
|
|
||||||
|
copy_m3_m4(mtx3_tx, mtx_tx);
|
||||||
|
|
||||||
|
/* calc the axis vec */
|
||||||
|
mul_m3_v3(mtx3_tx, axis_vec);
|
||||||
|
normalize_v3(axis_vec);
|
||||||
|
|
||||||
|
/* screw */
|
||||||
|
if(ltmd->flag & MOD_SCREW_OBJECT_OFFSET) {
|
||||||
|
/* find the offset along this axis relative to this objects matrix */
|
||||||
|
float totlen = len_v3(mtx_tx[3]);
|
||||||
|
|
||||||
|
if(totlen != 0.0f) {
|
||||||
|
float zero[3]={0.0f, 0.0f, 0.0f};
|
||||||
|
float cp[3];
|
||||||
|
screw_ofs= closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
screw_ofs= 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* angle */
|
||||||
|
|
||||||
|
#if 0 // cant incluide this, not pradictable enough, though quite fun,.
|
||||||
|
if(ltmd->flag & MOD_SCREW_OBJECT_ANGLE) {
|
||||||
|
|
||||||
|
|
||||||
|
float vec[3] = {0,1,0};
|
||||||
|
float cross1[3];
|
||||||
|
float cross2[3];
|
||||||
|
cross_v3_v3v3(cross1, vec, axis_vec);
|
||||||
|
|
||||||
|
mul_v3_m3v3(cross2, mtx3_tx, cross1);
|
||||||
|
{
|
||||||
|
float c1[3];
|
||||||
|
float c2[3];
|
||||||
|
float axis_tmp[3];
|
||||||
|
|
||||||
|
cross_v3_v3v3(c1, cross2, axis_vec);
|
||||||
|
cross_v3_v3v3(c2, axis_vec, c1);
|
||||||
|
|
||||||
|
|
||||||
|
angle= angle_v3v3(cross1, c2);
|
||||||
|
|
||||||
|
cross_v3_v3v3(axis_tmp, cross1, c2);
|
||||||
|
normalize_v3(axis_tmp);
|
||||||
|
|
||||||
|
if(len_v3v3(axis_tmp, axis_vec) > 1.0f)
|
||||||
|
angle= -angle;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* exis char is used by i_rotate*/
|
||||||
|
axis_char= 'X' + ltmd->axis;
|
||||||
|
|
||||||
|
/* useful to be able to use the axis vec in some cases still */
|
||||||
|
zero_v3(axis_vec);
|
||||||
|
axis_vec[ltmd->axis]= 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply the multiplier */
|
||||||
|
angle *= ltmd->iter;
|
||||||
|
screw_ofs *= ltmd->iter;
|
||||||
|
|
||||||
|
/* multiplying the steps is a bit tricky, this works best */
|
||||||
|
steps = ((steps + 1) * ltmd->iter) - (ltmd->iter - 1);
|
||||||
|
|
||||||
|
/* will the screw be closed?
|
||||||
|
* Note! smaller then FLT_EPSILON*100 gives problems with float precission so its never closed. */
|
||||||
|
if (fabs(screw_ofs) <= (FLT_EPSILON*100) && fabs(fabs(angle) - (M_PI * 2)) <= (FLT_EPSILON*100)) {
|
||||||
|
close= 1;
|
||||||
|
steps--;
|
||||||
|
if(steps < 2) steps= 2;
|
||||||
|
|
||||||
|
maxVerts = totvert * steps; /* -1 because we're joining back up */
|
||||||
|
maxEdges = (totvert * steps) + /* these are the edges between new verts */
|
||||||
|
(totedge * steps); /* -1 because vert edges join */
|
||||||
|
maxFaces = totedge * steps;
|
||||||
|
|
||||||
|
screw_ofs= 0.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
close= 0;
|
||||||
|
if(steps < 2) steps= 2;
|
||||||
|
|
||||||
|
maxVerts = totvert * steps; /* -1 because we're joining back up */
|
||||||
|
maxEdges = (totvert * (steps-1)) + /* these are the edges between new verts */
|
||||||
|
(totedge * steps); /* -1 because vert edges join */
|
||||||
|
maxFaces = totedge * (steps-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
result= CDDM_from_template(dm, maxVerts, maxEdges, maxFaces);
|
||||||
|
|
||||||
|
/* copy verts from mesh */
|
||||||
|
mvert_orig = dm->getVertArray(dm);
|
||||||
|
medge_orig = dm->getEdgeArray(dm);
|
||||||
|
|
||||||
|
mvert_new = result->getVertArray(result);
|
||||||
|
mface_new = result->getFaceArray(result);
|
||||||
|
medge_new = result->getEdgeArray(result);
|
||||||
|
|
||||||
|
origindex= result->getFaceDataArray(result, CD_ORIGINDEX);
|
||||||
|
|
||||||
|
/* Set the locations of the first set of verts */
|
||||||
|
|
||||||
|
mv_new= mvert_new;
|
||||||
|
mv_orig= mvert_orig;
|
||||||
|
|
||||||
|
/* Copy the first set of edges */
|
||||||
|
med_orig= medge_orig;
|
||||||
|
med_new= medge_new;
|
||||||
|
for (i=0; i < totedge; i++, med_orig++, med_new++) {
|
||||||
|
med_new->v1= med_orig->v1;
|
||||||
|
med_new->v2= med_orig->v2;
|
||||||
|
med_new->crease= med_orig->crease;
|
||||||
|
med_new->flag= med_orig->flag & ~ME_LOOSEEDGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ltmd->flag & MOD_SCREW_NORMAL_CALC) {
|
||||||
|
/*
|
||||||
|
* Normal Calculation (for face flipping)
|
||||||
|
* Sort edge verts for correct face flipping
|
||||||
|
* NOT REALLY NEEDED but face flipping is nice.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
/* Notice!
|
||||||
|
*
|
||||||
|
* Since we are only ordering the edges here it can avoid mallocing the
|
||||||
|
* extra space by abusing the vert array berfore its filled with new verts.
|
||||||
|
* The new array for vert_connect must be at least sizeof(ScrewVertConnect) * totvert
|
||||||
|
* and the size of our resulting meshes array is sizeof(MVert) * totvert * 3
|
||||||
|
* so its safe to use the second 2 thrids of MVert the array for vert_connect,
|
||||||
|
* just make sure ScrewVertConnect struct is no more then twice as big as MVert,
|
||||||
|
* at the moment there is no chance of that being a problem,
|
||||||
|
* unless MVert becomes half its current size.
|
||||||
|
*
|
||||||
|
* once the edges are ordered, vert_connect is not needed and it can be used for verts
|
||||||
|
*
|
||||||
|
* This makes the modifier faster with one less alloc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
vert_connect= MEM_mallocN(sizeof(ScrewVertConnect) * totvert, "ScrewVertConnect");
|
||||||
|
//vert_connect= (ScrewVertConnect *) &medge_new[totvert]; /* skip the first slice of verts */
|
||||||
|
vc= vert_connect;
|
||||||
|
|
||||||
|
/* Copy Vert Locations */
|
||||||
|
/* - We can do this in a later loop - only do here if no normal calc */
|
||||||
|
if (!totedge) {
|
||||||
|
for (i=0; i < totvert; i++, mv_orig++, mv_new++) {
|
||||||
|
copy_v3_v3(mv_new->co, mv_orig->co);
|
||||||
|
normalize_v3_v3(vc->no, mv_new->co); /* no edges- this is realy a dummy normal */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*printf("\n\n\n\n\nStarting Modifier\n");*/
|
||||||
|
/* set edge users */
|
||||||
|
med_new= medge_new;
|
||||||
|
mv_new= mvert_new;
|
||||||
|
|
||||||
|
if (ltmd->ob_axis) {
|
||||||
|
/*mtx_tx is initialized early on */
|
||||||
|
for (i=0; i < totvert; i++, mv_new++, mv_orig++, vc++) {
|
||||||
|
vc->co[0]= mv_new->co[0]= mv_orig->co[0];
|
||||||
|
vc->co[1]= mv_new->co[1]= mv_orig->co[1];
|
||||||
|
vc->co[2]= mv_new->co[2]= mv_orig->co[2];
|
||||||
|
|
||||||
|
vc->flag= 0;
|
||||||
|
vc->e[0]= vc->e[1]= NULL;
|
||||||
|
vc->v[0]= vc->v[1]= -1;
|
||||||
|
|
||||||
|
mul_m4_v3(mtx_tx, vc->co);
|
||||||
|
/* length in 2d, dont sqrt because this is only for comparison */
|
||||||
|
vc->dist = vc->co[other_axis_1]*vc->co[other_axis_1] +
|
||||||
|
vc->co[other_axis_2]*vc->co[other_axis_2];
|
||||||
|
|
||||||
|
/* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i=0; i < totvert; i++, mv_new++, mv_orig++, vc++) {
|
||||||
|
vc->co[0]= mv_new->co[0]= mv_orig->co[0];
|
||||||
|
vc->co[1]= mv_new->co[1]= mv_orig->co[1];
|
||||||
|
vc->co[2]= mv_new->co[2]= mv_orig->co[2];
|
||||||
|
|
||||||
|
vc->flag= 0;
|
||||||
|
vc->e[0]= vc->e[1]= NULL;
|
||||||
|
vc->v[0]= vc->v[1]= -1;
|
||||||
|
|
||||||
|
/* length in 2d, dont sqrt because this is only for comparison */
|
||||||
|
vc->dist = vc->co[other_axis_1]*vc->co[other_axis_1] +
|
||||||
|
vc->co[other_axis_2]*vc->co[other_axis_2];
|
||||||
|
|
||||||
|
/* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this loop builds connectivity info for verts */
|
||||||
|
for (i=0; i<totedge; i++, med_new++) {
|
||||||
|
vc= &vert_connect[med_new->v1];
|
||||||
|
|
||||||
|
if (vc->v[0]==-1) { /* unused */
|
||||||
|
vc->v[0]= med_new->v2;
|
||||||
|
vc->e[0]= med_new;
|
||||||
|
}
|
||||||
|
else if (vc->v[1]==-1) {
|
||||||
|
vc->v[1]= med_new->v2;
|
||||||
|
vc->e[1]= med_new;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vc->v[0]= vc->v[1]= -2; /* erro value - dont use, 3 edges on vert */
|
||||||
|
}
|
||||||
|
|
||||||
|
vc= &vert_connect[med_new->v2];
|
||||||
|
|
||||||
|
/* same as above but swap v1/2 */
|
||||||
|
if (vc->v[0]==-1) { /* unused */
|
||||||
|
vc->v[0]= med_new->v1;
|
||||||
|
vc->e[0]= med_new;
|
||||||
|
}
|
||||||
|
else if (vc->v[1]==-1) {
|
||||||
|
vc->v[1]= med_new->v1;
|
||||||
|
vc->e[1]= med_new;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vc->v[0]= vc->v[1]= -2; /* erro value - dont use, 3 edges on vert */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the first vert */
|
||||||
|
vc= vert_connect;
|
||||||
|
for (i=0; i < totvert; i++, vc++) {
|
||||||
|
int VBEST=-1, ed_loop_closed=0; /* vert and vert new */
|
||||||
|
int ed_loop_flip;
|
||||||
|
float fl= -1.0f;
|
||||||
|
ScrewVertIter lt_iter;
|
||||||
|
|
||||||
|
/* Now do search for connected verts, order all edges and flip them
|
||||||
|
* so resulting faces are flipped the right way */
|
||||||
|
vc_tot_linked= 0; /* count the number of linked verts for this loop */
|
||||||
|
if (vc->flag==0) {
|
||||||
|
/*printf("Loop on connected vert: %i\n", i);*/
|
||||||
|
|
||||||
|
for(j=0; j<2; j++) {
|
||||||
|
/*printf("\tSide: %i\n", j);*/
|
||||||
|
ScrewVertIter_INIT(lt_iter, vert_connect, i, j);
|
||||||
|
if (j==1) {
|
||||||
|
ScrewVertIter_NEXT(lt_iter);
|
||||||
|
}
|
||||||
|
while (lt_iter.v_poin) {
|
||||||
|
/*printf("\t\tVERT: %i\n", lt_iter.v);*/
|
||||||
|
if (lt_iter.v_poin->flag) {
|
||||||
|
/*printf("\t\t\tBreaking Found end\n");*/
|
||||||
|
//endpoints[0]= endpoints[1]= -1;
|
||||||
|
ed_loop_closed= 1; /* circle */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lt_iter.v_poin->flag= 1;
|
||||||
|
vc_tot_linked++;
|
||||||
|
/*printf("Testing 2 floats %f : %f\n", fl, lt_iter.v_poin->dist);*/
|
||||||
|
if (fl <= lt_iter.v_poin->dist) {
|
||||||
|
fl= lt_iter.v_poin->dist;
|
||||||
|
VBEST= lt_iter.v;
|
||||||
|
/*printf("\t\t\tVERT BEST: %i\n", VBEST);*/
|
||||||
|
}
|
||||||
|
ScrewVertIter_NEXT(lt_iter);
|
||||||
|
if (!lt_iter.v_poin) {
|
||||||
|
/*printf("\t\t\tFound End Also Num %i\n", j);*/
|
||||||
|
/*endpoints[j]= lt_iter.v_other;*/ /* other is still valid */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we have a collection of used edges. flip their edges the right way*/
|
||||||
|
/*if (VBEST !=-1) - */
|
||||||
|
|
||||||
|
/*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/
|
||||||
|
|
||||||
|
if (vc_tot_linked>1) {
|
||||||
|
float vf_1, vf_2, vf_best;
|
||||||
|
|
||||||
|
vc_tmp= &vert_connect[VBEST];
|
||||||
|
|
||||||
|
tmpf1= vert_connect[vc_tmp->v[0]].co;
|
||||||
|
tmpf2= vert_connect[vc_tmp->v[1]].co;
|
||||||
|
|
||||||
|
|
||||||
|
/* edge connects on each side! */
|
||||||
|
if ((vc_tmp->v[0] > -1) && (vc_tmp->v[1] > -1)) {
|
||||||
|
/*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
|
||||||
|
/* find out which is higher */
|
||||||
|
|
||||||
|
vf_1= tmpf1[ltmd->axis];
|
||||||
|
vf_2= tmpf2[ltmd->axis];
|
||||||
|
vf_best= vc_tmp->co[ltmd->axis];
|
||||||
|
|
||||||
|
if (vf_1 < vf_best && vf_best < vf_2) {
|
||||||
|
ed_loop_flip= 0;
|
||||||
|
}
|
||||||
|
else if (vf_1 > vf_best && vf_best > vf_2) {
|
||||||
|
ed_loop_flip= 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* not so simple to work out which edge is higher */
|
||||||
|
sub_v3_v3v3(tmp_vec1, tmpf1, vc_tmp->co);
|
||||||
|
sub_v3_v3v3(tmp_vec1, tmpf2, vc_tmp->co);
|
||||||
|
normalize_v3(tmp_vec1);
|
||||||
|
normalize_v3(tmp_vec2);
|
||||||
|
|
||||||
|
if (tmp_vec1[ltmd->axis] < tmp_vec2[ltmd->axis]) {
|
||||||
|
ed_loop_flip= 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ed_loop_flip= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vc_tmp->v[0] >= 0) { /*vertex only connected on 1 side */
|
||||||
|
/*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
|
||||||
|
if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */
|
||||||
|
ed_loop_flip= 1;
|
||||||
|
}
|
||||||
|
else { /* best is below or even... in even case we cant know whet to do. */
|
||||||
|
ed_loop_flip= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}/* else {
|
||||||
|
printf("No Connected ___\n");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*printf("flip direction %i\n", ed_loop_flip);*/
|
||||||
|
|
||||||
|
|
||||||
|
/* switch the flip option if set */
|
||||||
|
if (ltmd->flag & MOD_SCREW_NORMAL_FLIP)
|
||||||
|
ed_loop_flip= !ed_loop_flip;
|
||||||
|
|
||||||
|
if (angle < 0.0f)
|
||||||
|
ed_loop_flip= !ed_loop_flip;
|
||||||
|
|
||||||
|
/* if its closed, we only need 1 loop */
|
||||||
|
for(j=ed_loop_closed; j<2; j++) {
|
||||||
|
/*printf("Ordering Side J %i\n", j);*/
|
||||||
|
|
||||||
|
ScrewVertIter_INIT(lt_iter, vert_connect, VBEST, j);
|
||||||
|
/*printf("\n\nStarting - Loop\n");*/
|
||||||
|
lt_iter.v_poin->flag= 1; /* so a non loop will traverse the other side */
|
||||||
|
|
||||||
|
|
||||||
|
/* If this is the vert off the best vert and
|
||||||
|
* the best vert has 2 edges connected too it
|
||||||
|
* then swap the flip direction */
|
||||||
|
if (j==1 && (vc_tmp->v[0] > -1) && (vc_tmp->v[1] > -1))
|
||||||
|
ed_loop_flip= !ed_loop_flip;
|
||||||
|
|
||||||
|
while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) {
|
||||||
|
/*printf("\tOrdering Vert V %i\n", lt_iter.v);*/
|
||||||
|
|
||||||
|
lt_iter.v_poin->flag= 2;
|
||||||
|
if (lt_iter.e) {
|
||||||
|
if (lt_iter.v == lt_iter.e->v1) {
|
||||||
|
if (ed_loop_flip==0) {
|
||||||
|
/*printf("\t\t\tFlipping 0\n");*/
|
||||||
|
SWAP(int, lt_iter.e->v1, lt_iter.e->v2);
|
||||||
|
}/* else {
|
||||||
|
printf("\t\t\tFlipping Not 0\n");
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
else if (lt_iter.v == lt_iter.e->v2) {
|
||||||
|
if (ed_loop_flip==1) {
|
||||||
|
/*printf("\t\t\tFlipping 1\n");*/
|
||||||
|
SWAP(int, lt_iter.e->v1, lt_iter.e->v2);
|
||||||
|
}/* else {
|
||||||
|
printf("\t\t\tFlipping Not 1\n");
|
||||||
|
}*/
|
||||||
|
}/* else {
|
||||||
|
printf("\t\tIncorrect edge topology");
|
||||||
|
}*/
|
||||||
|
}/* else {
|
||||||
|
printf("\t\tNo Edge at this point\n");
|
||||||
|
}*/
|
||||||
|
ScrewVertIter_NEXT(lt_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *VERTEX NORMALS*
|
||||||
|
* we know the surrounding edges are ordered correctly now
|
||||||
|
* so its safe to create vertex normals.
|
||||||
|
*
|
||||||
|
* calculate vertex normals that can be propodated on lathing
|
||||||
|
* use edge connectivity work this out */
|
||||||
|
if (vc->v[0]>=0) {
|
||||||
|
if (vc->v[1]>=0) {
|
||||||
|
/* 2 edges connedted */
|
||||||
|
/* make 2 connecting vert locations relative to the middle vert */
|
||||||
|
sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
|
||||||
|
sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co);
|
||||||
|
/* normalize so both edges have the same influence, no matter their length */
|
||||||
|
normalize_v3(tmp_vec1);
|
||||||
|
normalize_v3(tmp_vec2);
|
||||||
|
|
||||||
|
/* vc_no_tmp1 - this line is the average direction of both connecting edges
|
||||||
|
*
|
||||||
|
* Use the edge order to make the subtraction, flip the normal the right way
|
||||||
|
* edge should be there but check just in case... */
|
||||||
|
if (vc->e && vc->e[0]->v1 == i) {
|
||||||
|
sub_v3_v3v3(tmp_vec1, tmp_vec1, tmp_vec2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* only 1 edge connected - same as above except
|
||||||
|
* dont need to average edge direction */
|
||||||
|
if (vc->e && vc->e[0]->v2 == i) {
|
||||||
|
sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vc_no_tmp2 - is a line 90d from the pivot to the vec
|
||||||
|
* This is used so the resulting normal points directly away from the middle */
|
||||||
|
cross_v3_v3v3(tmp_vec2, axis_vec, vc->co);
|
||||||
|
|
||||||
|
/* edge average vector and right angle to the pivot make the normal */
|
||||||
|
cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
copy_v3_v3(vc->no, vc->co);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we wont be looping on this data again so copy normals here */
|
||||||
|
if (angle < 0.0f)
|
||||||
|
negate_v3(vc->no);
|
||||||
|
|
||||||
|
normalize_v3(vc->no);
|
||||||
|
normal_float_to_short_v3(mvert_new[i].no, vc->no);
|
||||||
|
|
||||||
|
/* Done with normals */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (ltmd->flag & MOD_SCREW_NORMAL_FLIP) {
|
||||||
|
mv_orig= mvert_orig;
|
||||||
|
mv_new= mvert_new + (totvert-1);
|
||||||
|
|
||||||
|
for (i=0; i < totvert; i++, mv_new--, mv_orig++) {
|
||||||
|
copy_v3_v3(mv_new->co, mv_orig->co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mv_orig= mvert_orig;
|
||||||
|
mv_new= mvert_new;
|
||||||
|
|
||||||
|
for (i=0; i < totvert; i++, mv_new++, mv_orig++) {
|
||||||
|
copy_v3_v3(mv_new->co, mv_orig->co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* done with edge connectivity based normal flipping */
|
||||||
|
|
||||||
|
|
||||||
|
/* Add Faces */
|
||||||
|
for (i=1; i < steps; i++) {
|
||||||
|
float step_angle;
|
||||||
|
float no_tx[3];
|
||||||
|
/* Rotation Matrix */
|
||||||
|
if (close) step_angle= (angle / steps) * i;
|
||||||
|
else step_angle= (angle / (steps-1)) * i;
|
||||||
|
|
||||||
|
if (ltmd->ob_axis) {
|
||||||
|
axis_angle_to_mat3(mat3, axis_vec, step_angle);
|
||||||
|
copy_m4_m3(mat, mat3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unit_m4(mat);
|
||||||
|
rotate_m4(mat, axis_char, step_angle);
|
||||||
|
copy_m3_m4(mat3, mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(screw_ofs)
|
||||||
|
madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)i / (float)(steps-1)));
|
||||||
|
|
||||||
|
mv_new_base= mvert_new;
|
||||||
|
mv_new= &mvert_new[totvert*i]; /* advance to the next slice */
|
||||||
|
|
||||||
|
for (j=0; j<totvert; j++, mv_new_base++, mv_new++) {
|
||||||
|
/* set normal */
|
||||||
|
if(vert_connect) {
|
||||||
|
mul_v3_m3v3(no_tx, mat3, vert_connect[j].no);
|
||||||
|
|
||||||
|
/* set the normal now its transformed */
|
||||||
|
normal_float_to_short_v3(mv_new->no, no_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set location */
|
||||||
|
copy_v3_v3(mv_new->co, mv_new_base->co);
|
||||||
|
|
||||||
|
/* only need to set these if using non cleared memory */
|
||||||
|
/*mv_new->mat_nr= mv_new->flag= 0;*/
|
||||||
|
|
||||||
|
if (ltmd->ob_axis) {
|
||||||
|
sub_v3_v3(mv_new->co, mtx_tx[3]);
|
||||||
|
|
||||||
|
mul_m4_v3(mat, mv_new->co);
|
||||||
|
|
||||||
|
add_v3_v3(mv_new->co, mtx_tx[3]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mul_m4_v3(mat, mv_new->co);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the new edge */
|
||||||
|
med_new->v1= j+(i*totvert);
|
||||||
|
med_new->v2= med_new->v1 - totvert;
|
||||||
|
med_new->flag= ME_EDGEDRAW|ME_EDGERENDER;
|
||||||
|
med_new++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we can avoid if using vert alloc trick */
|
||||||
|
if(vert_connect) {
|
||||||
|
MEM_freeN(vert_connect);
|
||||||
|
vert_connect= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close) {
|
||||||
|
/* last loop of edges, previous loop dosnt account for the last set of edges */
|
||||||
|
for (i=0; i<totvert; i++) {
|
||||||
|
med_new->v1= i;
|
||||||
|
med_new->v2= i+((steps-1)*totvert);
|
||||||
|
med_new->flag= ME_EDGEDRAW|ME_EDGERENDER;
|
||||||
|
med_new++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mf_new= mface_new;
|
||||||
|
med_new_firstloop= medge_new;
|
||||||
|
|
||||||
|
for (i=0; i < totedge; i++, med_new_firstloop++) {
|
||||||
|
/* for each edge, make a cylinder of quads */
|
||||||
|
i1= med_new_firstloop->v1;
|
||||||
|
i2= med_new_firstloop->v2;
|
||||||
|
|
||||||
|
for (j=0; j < steps-1; j++) {
|
||||||
|
|
||||||
|
/* new face */
|
||||||
|
mf_new->v1= i1;
|
||||||
|
mf_new->v2= i2;
|
||||||
|
mf_new->v3= i2 + totvert;
|
||||||
|
mf_new->v4= i1 + totvert;
|
||||||
|
|
||||||
|
if( !mf_new->v3 || !mf_new->v4 ) {
|
||||||
|
SWAP(int, mf_new->v1, mf_new->v3);
|
||||||
|
SWAP(int, mf_new->v2, mf_new->v4);
|
||||||
|
}
|
||||||
|
mf_new->flag= ME_SMOOTH;
|
||||||
|
origindex[mface_index]= ORIGINDEX_NONE;
|
||||||
|
mf_new++;
|
||||||
|
mface_index++;
|
||||||
|
|
||||||
|
/* new vertical edge */
|
||||||
|
if (j) { /* The first set is alredy dome */
|
||||||
|
med_new->v1= i1;
|
||||||
|
med_new->v2= i2;
|
||||||
|
med_new->flag= med_new_firstloop->flag;
|
||||||
|
med_new->crease= med_new_firstloop->crease;
|
||||||
|
med_new++;
|
||||||
|
}
|
||||||
|
i1 += totvert;
|
||||||
|
i2 += totvert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close the loop*/
|
||||||
|
if (close) {
|
||||||
|
mf_new->v1= i1;
|
||||||
|
mf_new->v2= i2;
|
||||||
|
mf_new->v3= med_new_firstloop->v2;
|
||||||
|
mf_new->v4= med_new_firstloop->v1;
|
||||||
|
|
||||||
|
if( !mf_new->v3 || !mf_new->v4 ) {
|
||||||
|
SWAP(int, mf_new->v1, mf_new->v3);
|
||||||
|
SWAP(int, mf_new->v2, mf_new->v4);
|
||||||
|
}
|
||||||
|
mf_new->flag= ME_SMOOTH;
|
||||||
|
origindex[mface_index]= ORIGINDEX_NONE;
|
||||||
|
mf_new++;
|
||||||
|
mface_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* new vertical edge */
|
||||||
|
med_new->v1= i1;
|
||||||
|
med_new->v2= i2;
|
||||||
|
med_new->flag= med_new_firstloop->flag & ~ME_LOOSEEDGE;
|
||||||
|
med_new->crease= med_new_firstloop->crease;
|
||||||
|
med_new++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ltmd->flag & MOD_SCREW_NORMAL_CALC)==0) {
|
||||||
|
CDDM_calc_normals(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest,
|
||||||
|
Scene *scene, Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
ScrewModifierData *ltmd= (ScrewModifierData*) md;
|
||||||
|
|
||||||
|
if(ltmd->ob_axis) {
|
||||||
|
DagNode *curNode= dag_get_node(forest, ltmd->ob_axis);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
|
||||||
|
"Screw Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
void (*walk)(void *userData, Object *ob, Object **obpoin),
|
||||||
|
void *userData)
|
||||||
|
{
|
||||||
|
ScrewModifierData *ltmd= (ScrewModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, <md->ob_axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This dosnt work with material*/
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Screw = {
|
||||||
|
/* name */ "Screw",
|
||||||
|
/* structName */ "ScrewModifierData",
|
||||||
|
/* structSize */ sizeof(ScrewModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
157
source/blender/modifiers/intern/MOD_shapekey.c
Normal file
157
source/blender/modifiers/intern/MOD_shapekey.c
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
KeyBlock *kb= ob_get_keyblock(ob);
|
||||||
|
float (*deformedVerts)[3];
|
||||||
|
|
||||||
|
if(kb && kb->totelem == numVerts) {
|
||||||
|
deformedVerts= (float(*)[3])do_ob_key(md->scene, ob);
|
||||||
|
if(deformedVerts) {
|
||||||
|
memcpy(vertexCos, deformedVerts, sizeof(float)*3*numVerts);
|
||||||
|
MEM_freeN(deformedVerts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
Key *key= ob_get_key(ob);
|
||||||
|
|
||||||
|
if(key && key->type == KEY_RELATIVE)
|
||||||
|
deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformMatricesEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3],
|
||||||
|
float (*defMats)[3][3], int numVerts)
|
||||||
|
{
|
||||||
|
Key *key= ob_get_key(ob);
|
||||||
|
KeyBlock *kb= ob_get_keyblock(ob);
|
||||||
|
float scale[3][3];
|
||||||
|
int a;
|
||||||
|
|
||||||
|
if(kb && kb->totelem==numVerts && kb!=key->refkey) {
|
||||||
|
scale_m3_fl(scale, kb->curval);
|
||||||
|
|
||||||
|
for(a=0; a<numVerts; a++)
|
||||||
|
copy_m3_m3(defMats[a], scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_ShapeKey = {
|
||||||
|
/* name */ "ShapeKey",
|
||||||
|
/* structName */ "ShapeKeyModifierData",
|
||||||
|
/* structSize */ sizeof(ShapeKeyModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ 0,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ deformMatricesEM,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
218
source/blender/modifiers/intern/MOD_shrinkwrap.c
Normal file
218
source/blender/modifiers/intern/MOD_shrinkwrap.c
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Shrinkwrap */
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
|
||||||
|
smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
|
||||||
|
smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
|
||||||
|
smd->keepDist = 0.0f;
|
||||||
|
|
||||||
|
smd->target = NULL;
|
||||||
|
smd->auxTarget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*)md;
|
||||||
|
ShrinkwrapModifierData *tsmd = (ShrinkwrapModifierData*)target;
|
||||||
|
|
||||||
|
tsmd->target = smd->target;
|
||||||
|
tsmd->auxTarget = smd->auxTarget;
|
||||||
|
|
||||||
|
strcpy(tsmd->vgroup_name, smd->vgroup_name);
|
||||||
|
|
||||||
|
tsmd->keepDist = smd->keepDist;
|
||||||
|
tsmd->shrinkType= smd->shrinkType;
|
||||||
|
tsmd->shrinkOpts= smd->shrinkOpts;
|
||||||
|
tsmd->projAxis = smd->projAxis;
|
||||||
|
tsmd->subsurfLevels = smd->subsurfLevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(smd->vgroup_name[0])
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
if(smd->shrinkType == MOD_SHRINKWRAP_PROJECT
|
||||||
|
&& smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
|
||||||
|
dataMask |= (1 << CD_MVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
|
||||||
|
return !smd->target;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &smd->target);
|
||||||
|
walk(userData, ob, &smd->auxTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
CustomDataMask dataMask = requiredDataMask(ob, md);
|
||||||
|
|
||||||
|
/* ensure we get a CDDM with applied vertex coords */
|
||||||
|
if(dataMask)
|
||||||
|
dm= get_cddm(md->scene, ob, NULL, dm, vertexCos);
|
||||||
|
|
||||||
|
shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
CustomDataMask dataMask = requiredDataMask(ob, md);
|
||||||
|
|
||||||
|
/* ensure we get a CDDM with applied vertex coords */
|
||||||
|
if(dataMask)
|
||||||
|
dm= get_cddm(md->scene, ob, editData, dm, vertexCos);
|
||||||
|
|
||||||
|
shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
|
||||||
|
|
||||||
|
if (smd->target)
|
||||||
|
dag_add_relation(forest, dag_get_node(forest, smd->target), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
|
||||||
|
|
||||||
|
if (smd->auxTarget)
|
||||||
|
dag_add_relation(forest, dag_get_node(forest, smd->auxTarget), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Shrinkwrap = {
|
||||||
|
/* name */ "Shrinkwrap",
|
||||||
|
/* structName */ "ShrinkwrapModifierData",
|
||||||
|
/* structSize */ sizeof(ShrinkwrapModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
424
source/blender/modifiers/intern/MOD_simpledeform.c
Normal file
424
source/blender/modifiers/intern/MOD_simpledeform.c
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "DNA_object_types.h"
|
||||||
|
#include "DNA_modifier_types.h"
|
||||||
|
#include "DNA_meshdata_types.h"
|
||||||
|
|
||||||
|
#include "BKE_DerivedMesh.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_utildefines.h"
|
||||||
|
#include "BLI_math.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1]
|
||||||
|
* The ammount of clamp is saved on dcut */
|
||||||
|
static void axis_limit(int axis, const float limits[2], float co[3], float dcut[3])
|
||||||
|
{
|
||||||
|
float val = co[axis];
|
||||||
|
if(limits[0] > val) val = limits[0];
|
||||||
|
if(limits[1] < val) val = limits[1];
|
||||||
|
|
||||||
|
dcut[axis] = co[axis] - val;
|
||||||
|
co[axis] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simpleDeform_taper(const float factor, const float dcut[3], float *co)
|
||||||
|
{
|
||||||
|
float x = co[0], y = co[1], z = co[2];
|
||||||
|
float scale = z*factor;
|
||||||
|
|
||||||
|
co[0] = x + x*scale;
|
||||||
|
co[1] = y + y*scale;
|
||||||
|
co[2] = z;
|
||||||
|
|
||||||
|
if(dcut)
|
||||||
|
{
|
||||||
|
co[0] += dcut[0];
|
||||||
|
co[1] += dcut[1];
|
||||||
|
co[2] += dcut[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simpleDeform_stretch(const float factor, const float dcut[3], float *co)
|
||||||
|
{
|
||||||
|
float x = co[0], y = co[1], z = co[2];
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
scale = (z*z*factor-factor + 1.0);
|
||||||
|
|
||||||
|
co[0] = x*scale;
|
||||||
|
co[1] = y*scale;
|
||||||
|
co[2] = z*(1.0+factor);
|
||||||
|
|
||||||
|
|
||||||
|
if(dcut)
|
||||||
|
{
|
||||||
|
co[0] += dcut[0];
|
||||||
|
co[1] += dcut[1];
|
||||||
|
co[2] += dcut[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simpleDeform_twist(const float factor, const float *dcut, float *co)
|
||||||
|
{
|
||||||
|
float x = co[0], y = co[1], z = co[2];
|
||||||
|
float theta, sint, cost;
|
||||||
|
|
||||||
|
theta = z*factor;
|
||||||
|
sint = sin(theta);
|
||||||
|
cost = cos(theta);
|
||||||
|
|
||||||
|
co[0] = x*cost - y*sint;
|
||||||
|
co[1] = x*sint + y*cost;
|
||||||
|
co[2] = z;
|
||||||
|
|
||||||
|
if(dcut)
|
||||||
|
{
|
||||||
|
co[0] += dcut[0];
|
||||||
|
co[1] += dcut[1];
|
||||||
|
co[2] += dcut[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simpleDeform_bend(const float factor, const float dcut[3], float *co)
|
||||||
|
{
|
||||||
|
float x = co[0], y = co[1], z = co[2];
|
||||||
|
float theta, sint, cost;
|
||||||
|
|
||||||
|
theta = x*factor;
|
||||||
|
sint = sin(theta);
|
||||||
|
cost = cos(theta);
|
||||||
|
|
||||||
|
if(fabs(factor) > 1e-7f)
|
||||||
|
{
|
||||||
|
co[0] = -(y-1.0f/factor)*sint;
|
||||||
|
co[1] = (y-1.0f/factor)*cost + 1.0f/factor;
|
||||||
|
co[2] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(dcut)
|
||||||
|
{
|
||||||
|
co[0] += cost*dcut[0];
|
||||||
|
co[1] += sint*dcut[0];
|
||||||
|
co[2] += dcut[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* simple deform modifier */
|
||||||
|
void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
static const float lock_axis[2] = {0.0f, 0.0f};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int limit_axis = 0;
|
||||||
|
float smd_limit[2], smd_factor;
|
||||||
|
SpaceTransform *transf = NULL, tmp_transf;
|
||||||
|
void (*simpleDeform_callback)(const float factor, const float dcut[3], float *co) = NULL; //Mode callback
|
||||||
|
int vgroup = defgroup_name_index(ob, smd->vgroup_name);
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
|
||||||
|
//Safe-check
|
||||||
|
if(smd->origin == ob) smd->origin = NULL; //No self references
|
||||||
|
|
||||||
|
if(smd->limit[0] < 0.0) smd->limit[0] = 0.0f;
|
||||||
|
if(smd->limit[0] > 1.0) smd->limit[0] = 1.0f;
|
||||||
|
|
||||||
|
smd->limit[0] = MIN2(smd->limit[0], smd->limit[1]); //Upper limit >= than lower limit
|
||||||
|
|
||||||
|
//Calculate matrixs do convert between coordinate spaces
|
||||||
|
if(smd->origin)
|
||||||
|
{
|
||||||
|
transf = &tmp_transf;
|
||||||
|
|
||||||
|
if(smd->originOpts & MOD_SIMPLEDEFORM_ORIGIN_LOCAL)
|
||||||
|
{
|
||||||
|
space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copy_m4_m4(transf->local2target, smd->origin->obmat);
|
||||||
|
invert_m4_m4(transf->target2local, transf->local2target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup vars
|
||||||
|
limit_axis = (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) ? 0 : 2; //Bend limits on X.. all other modes limit on Z
|
||||||
|
|
||||||
|
//Update limits if needed
|
||||||
|
{
|
||||||
|
float lower = FLT_MAX;
|
||||||
|
float upper = -FLT_MAX;
|
||||||
|
|
||||||
|
for(i=0; i<numVerts; i++)
|
||||||
|
{
|
||||||
|
float tmp[3];
|
||||||
|
VECCOPY(tmp, vertexCos[i]);
|
||||||
|
|
||||||
|
if(transf) space_transform_apply(transf, tmp);
|
||||||
|
|
||||||
|
lower = MIN2(lower, tmp[limit_axis]);
|
||||||
|
upper = MAX2(upper, tmp[limit_axis]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//SMD values are normalized to the BV, calculate the absolut values
|
||||||
|
smd_limit[1] = lower + (upper-lower)*smd->limit[1];
|
||||||
|
smd_limit[0] = lower + (upper-lower)*smd->limit[0];
|
||||||
|
|
||||||
|
smd_factor = smd->factor / MAX2(FLT_EPSILON, smd_limit[1]-smd_limit[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(dm)
|
||||||
|
{
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
}
|
||||||
|
else if(ob->type == OB_LATTICE)
|
||||||
|
{
|
||||||
|
dvert = lattice_get_deform_verts(ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch(smd->mode)
|
||||||
|
{
|
||||||
|
case MOD_SIMPLEDEFORM_MODE_TWIST: simpleDeform_callback = simpleDeform_twist; break;
|
||||||
|
case MOD_SIMPLEDEFORM_MODE_BEND: simpleDeform_callback = simpleDeform_bend; break;
|
||||||
|
case MOD_SIMPLEDEFORM_MODE_TAPER: simpleDeform_callback = simpleDeform_taper; break;
|
||||||
|
case MOD_SIMPLEDEFORM_MODE_STRETCH: simpleDeform_callback = simpleDeform_stretch; break;
|
||||||
|
default:
|
||||||
|
return; //No simpledeform mode?
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<numVerts; i++)
|
||||||
|
{
|
||||||
|
float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
|
||||||
|
|
||||||
|
if(weight != 0.0f)
|
||||||
|
{
|
||||||
|
float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
if(transf) space_transform_apply(transf, vertexCos[i]);
|
||||||
|
|
||||||
|
VECCOPY(co, vertexCos[i]);
|
||||||
|
|
||||||
|
//Apply axis limits
|
||||||
|
if(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) //Bend mode shoulnt have any lock axis
|
||||||
|
{
|
||||||
|
if(smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) axis_limit(0, lock_axis, co, dcut);
|
||||||
|
if(smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) axis_limit(1, lock_axis, co, dcut);
|
||||||
|
}
|
||||||
|
axis_limit(limit_axis, smd_limit, co, dcut);
|
||||||
|
|
||||||
|
simpleDeform_callback(smd_factor, dcut, co); //Apply deform
|
||||||
|
interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); //Use vertex weight has coef of linear interpolation
|
||||||
|
|
||||||
|
if(transf) space_transform_invert(transf, vertexCos[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* SimpleDeform */
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
|
||||||
|
|
||||||
|
smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
|
||||||
|
smd->axis = 0;
|
||||||
|
|
||||||
|
smd->origin = NULL;
|
||||||
|
smd->factor = 0.35f;
|
||||||
|
smd->limit[0] = 0.0f;
|
||||||
|
smd->limit[1] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
SimpleDeformModifierData *smd = (SimpleDeformModifierData*)md;
|
||||||
|
SimpleDeformModifierData *tsmd = (SimpleDeformModifierData*)target;
|
||||||
|
|
||||||
|
tsmd->mode = smd->mode;
|
||||||
|
tsmd->axis = smd->axis;
|
||||||
|
tsmd->origin= smd->origin;
|
||||||
|
tsmd->factor= smd->factor;
|
||||||
|
memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(smd->vgroup_name[0])
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
|
||||||
|
{
|
||||||
|
SimpleDeformModifierData *smd = (SimpleDeformModifierData*)md;
|
||||||
|
walk(userData, ob, &smd->origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
SimpleDeformModifierData *smd = (SimpleDeformModifierData*)md;
|
||||||
|
|
||||||
|
if (smd->origin)
|
||||||
|
dag_add_relation(forest, dag_get_node(forest, smd->origin), obNode, DAG_RL_OB_DATA, "SimpleDeform Modifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
CustomDataMask dataMask = requiredDataMask(ob, md);
|
||||||
|
|
||||||
|
/* we implement requiredDataMask but thats not really usefull since
|
||||||
|
mesh_calc_modifiers pass a NULL derivedData */
|
||||||
|
if(dataMask)
|
||||||
|
dm= get_dm(md->scene, ob, NULL, dm, NULL, 0);
|
||||||
|
|
||||||
|
SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm = derivedData;
|
||||||
|
CustomDataMask dataMask = requiredDataMask(ob, md);
|
||||||
|
|
||||||
|
/* we implement requiredDataMask but thats not really usefull since
|
||||||
|
mesh_calc_modifiers pass a NULL derivedData */
|
||||||
|
if(dataMask)
|
||||||
|
dm= get_dm(md->scene, ob, editData, dm, NULL, 0);
|
||||||
|
|
||||||
|
SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_SimpleDeform = {
|
||||||
|
/* name */ "SimpleDeform",
|
||||||
|
/* structName */ "SimpleDeformModifierData",
|
||||||
|
/* structSize */ sizeof(SimpleDeformModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
181
source/blender/modifiers/intern/MOD_smoke.c
Normal file
181
source/blender/modifiers/intern/MOD_smoke.c
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SmokeModifierData *smd = (SmokeModifierData*) md;
|
||||||
|
|
||||||
|
smd->domain = NULL;
|
||||||
|
smd->flow = NULL;
|
||||||
|
smd->coll = NULL;
|
||||||
|
smd->type = 0;
|
||||||
|
smd->time = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SmokeModifierData *smd = (SmokeModifierData*) md;
|
||||||
|
|
||||||
|
smokeModifier_free (smd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
SmokeModifierData *smd = (SmokeModifierData*) md;
|
||||||
|
DerivedMesh *dm = dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos);
|
||||||
|
|
||||||
|
smokeModifier_do(smd, md->scene, ob, dm, useRenderParams, isFinalCalc);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
/*SmokeModifierData *smd = (SmokeModifierData *) md;
|
||||||
|
if(smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
|
||||||
|
{
|
||||||
|
if(smd->domain->fluid_group)
|
||||||
|
{
|
||||||
|
GroupObject *go = NULL;
|
||||||
|
|
||||||
|
for(go = smd->domain->fluid_group->gobject.first; go; go = go->next)
|
||||||
|
{
|
||||||
|
if(go->ob)
|
||||||
|
{
|
||||||
|
SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
|
||||||
|
|
||||||
|
// check for initialized smoke object
|
||||||
|
if(smd2 && (smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
|
||||||
|
{
|
||||||
|
DagNode *curNode = dag_get_node(forest, go->ob);
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Smoke Flow");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Smoke = {
|
||||||
|
/* name */ "Smoke",
|
||||||
|
/* structName */ "SmokeModifierData",
|
||||||
|
/* structSize */ sizeof(SmokeModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_UsesPointCache
|
||||||
|
| eModifierTypeFlag_Single,
|
||||||
|
|
||||||
|
/* copyData */ 0,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
313
source/blender/modifiers/intern/MOD_smooth.c
Normal file
313
source/blender/modifiers/intern/MOD_smooth.c
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SmoothModifierData *smd = (SmoothModifierData*) md;
|
||||||
|
|
||||||
|
smd->fac = 0.5f;
|
||||||
|
smd->repeat = 1;
|
||||||
|
smd->flag = MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z;
|
||||||
|
smd->defgrp_name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
SmoothModifierData *smd = (SmoothModifierData*) md;
|
||||||
|
SmoothModifierData *tsmd = (SmoothModifierData*) target;
|
||||||
|
|
||||||
|
tsmd->fac = smd->fac;
|
||||||
|
tsmd->repeat = smd->repeat;
|
||||||
|
tsmd->flag = smd->flag;
|
||||||
|
strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
SmoothModifierData *smd = (SmoothModifierData*) md;
|
||||||
|
short flag;
|
||||||
|
|
||||||
|
flag = smd->flag & (MOD_SMOOTH_X|MOD_SMOOTH_Y|MOD_SMOOTH_Z);
|
||||||
|
|
||||||
|
/* disable if modifier is off for X, Y and Z or if factor is 0 */
|
||||||
|
if((smd->fac == 0.0f) || flag == 0) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
SmoothModifierData *smd = (SmoothModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(smd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smoothModifier_do(
|
||||||
|
SmoothModifierData *smd, Object *ob, DerivedMesh *dm,
|
||||||
|
float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
MEdge *medges = NULL;
|
||||||
|
|
||||||
|
int i, j, numDMEdges, defgrp_index;
|
||||||
|
unsigned char *uctmp;
|
||||||
|
float *ftmp, fac, facm;
|
||||||
|
|
||||||
|
ftmp = (float*)MEM_callocN(3*sizeof(float)*numVerts,
|
||||||
|
"smoothmodifier_f");
|
||||||
|
if (!ftmp) return;
|
||||||
|
uctmp = (unsigned char*)MEM_callocN(sizeof(unsigned char)*numVerts,
|
||||||
|
"smoothmodifier_uc");
|
||||||
|
if (!uctmp) {
|
||||||
|
if (ftmp) MEM_freeN(ftmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fac = smd->fac;
|
||||||
|
facm = 1 - fac;
|
||||||
|
|
||||||
|
medges = dm->getEdgeArray(dm);
|
||||||
|
numDMEdges = dm->getNumEdges(dm);
|
||||||
|
|
||||||
|
defgrp_index = defgroup_name_index(ob, smd->defgrp_name);
|
||||||
|
|
||||||
|
if (defgrp_index >= 0)
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
/* NOTICE: this can be optimized a little bit by moving the
|
||||||
|
* if (dvert) out of the loop, if needed */
|
||||||
|
for (j = 0; j < smd->repeat; j++) {
|
||||||
|
for (i = 0; i < numDMEdges; i++) {
|
||||||
|
float fvec[3];
|
||||||
|
float *v1, *v2;
|
||||||
|
unsigned int idx1, idx2;
|
||||||
|
|
||||||
|
idx1 = medges[i].v1;
|
||||||
|
idx2 = medges[i].v2;
|
||||||
|
|
||||||
|
v1 = vertexCos[idx1];
|
||||||
|
v2 = vertexCos[idx2];
|
||||||
|
|
||||||
|
fvec[0] = (v1[0] + v2[0]) / 2.0;
|
||||||
|
fvec[1] = (v1[1] + v2[1]) / 2.0;
|
||||||
|
fvec[2] = (v1[2] + v2[2]) / 2.0;
|
||||||
|
|
||||||
|
v1 = &ftmp[idx1*3];
|
||||||
|
v2 = &ftmp[idx2*3];
|
||||||
|
|
||||||
|
if (uctmp[idx1] < 255) {
|
||||||
|
uctmp[idx1]++;
|
||||||
|
add_v3_v3v3(v1, v1, fvec);
|
||||||
|
}
|
||||||
|
if (uctmp[idx2] < 255) {
|
||||||
|
uctmp[idx2]++;
|
||||||
|
add_v3_v3v3(v2, v2, fvec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvert) {
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
MDeformWeight *dw = NULL;
|
||||||
|
float f, fm, facw, *fp, *v;
|
||||||
|
int k;
|
||||||
|
short flag = smd->flag;
|
||||||
|
|
||||||
|
v = vertexCos[i];
|
||||||
|
fp = &ftmp[i*3];
|
||||||
|
|
||||||
|
for (k = 0; k < dvert[i].totweight; ++k) {
|
||||||
|
if(dvert[i].dw[k].def_nr == defgrp_index) {
|
||||||
|
dw = &dvert[i].dw[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dw) continue;
|
||||||
|
|
||||||
|
f = fac * dw->weight;
|
||||||
|
fm = 1.0f - f;
|
||||||
|
|
||||||
|
/* fp is the sum of uctmp[i] verts, so must be averaged */
|
||||||
|
facw = 0.0f;
|
||||||
|
if (uctmp[i])
|
||||||
|
facw = f / (float)uctmp[i];
|
||||||
|
|
||||||
|
if (flag & MOD_SMOOTH_X)
|
||||||
|
v[0] = fm * v[0] + facw * fp[0];
|
||||||
|
if (flag & MOD_SMOOTH_Y)
|
||||||
|
v[1] = fm * v[1] + facw * fp[1];
|
||||||
|
if (flag & MOD_SMOOTH_Z)
|
||||||
|
v[2] = fm * v[2] + facw * fp[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { /* no vertex group */
|
||||||
|
for (i = 0; i < numVerts; i++) {
|
||||||
|
float facw, *fp, *v;
|
||||||
|
short flag = smd->flag;
|
||||||
|
|
||||||
|
v = vertexCos[i];
|
||||||
|
fp = &ftmp[i*3];
|
||||||
|
|
||||||
|
/* fp is the sum of uctmp[i] verts, so must be averaged */
|
||||||
|
facw = 0.0f;
|
||||||
|
if (uctmp[i])
|
||||||
|
facw = fac / (float)uctmp[i];
|
||||||
|
|
||||||
|
if (flag & MOD_SMOOTH_X)
|
||||||
|
v[0] = facm * v[0] + facw * fp[0];
|
||||||
|
if (flag & MOD_SMOOTH_Y)
|
||||||
|
v[1] = facm * v[1] + facw * fp[1];
|
||||||
|
if (flag & MOD_SMOOTH_Z)
|
||||||
|
v[2] = facm * v[2] + facw * fp[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(ftmp, 0, 3*sizeof(float)*numVerts);
|
||||||
|
memset(uctmp, 0, sizeof(unsigned char)*numVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(ftmp);
|
||||||
|
MEM_freeN(uctmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
|
||||||
|
|
||||||
|
smoothModifier_do((SmoothModifierData *)md, ob, dm,
|
||||||
|
vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= get_dm(md->scene, ob, editData, derivedData, NULL, 0);
|
||||||
|
|
||||||
|
smoothModifier_do((SmoothModifierData *)md, ob, dm,
|
||||||
|
vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Smooth = {
|
||||||
|
/* name */ "Smooth",
|
||||||
|
/* structName */ "SmoothModifierData",
|
||||||
|
/* structSize */ sizeof(SmoothModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh |
|
||||||
|
eModifierTypeFlag_SupportsEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
125
source/blender/modifiers/intern/MOD_softbody.c
Normal file
125
source/blender/modifiers/intern/MOD_softbody.c
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
sbObjectStep(md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Softbody = {
|
||||||
|
/* name */ "Softbody",
|
||||||
|
/* structName */ "SoftbodyModifierData",
|
||||||
|
/* structSize */ sizeof(SoftbodyModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_RequiresOriginalData
|
||||||
|
| eModifierTypeFlag_Single,
|
||||||
|
|
||||||
|
/* copyData */ 0,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ 0,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
692
source/blender/modifiers/intern/MOD_solidify.c
Normal file
692
source/blender/modifiers/intern/MOD_solidify.c
Normal file
@@ -0,0 +1,692 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct EdgeFaceRef {
|
||||||
|
int f1; /* init as -1 */
|
||||||
|
int f2;
|
||||||
|
} EdgeFaceRef;
|
||||||
|
|
||||||
|
static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
|
||||||
|
{
|
||||||
|
int i, numVerts, numEdges, numFaces;
|
||||||
|
MFace *mface, *mf;
|
||||||
|
MVert *mvert, *mv;
|
||||||
|
|
||||||
|
float (*face_nors)[3];
|
||||||
|
float *f_no;
|
||||||
|
int calc_face_nors= 0;
|
||||||
|
|
||||||
|
numVerts = dm->getNumVerts(dm);
|
||||||
|
numEdges = dm->getNumEdges(dm);
|
||||||
|
numFaces = dm->getNumFaces(dm);
|
||||||
|
mface = dm->getFaceArray(dm);
|
||||||
|
mvert = dm->getVertArray(dm);
|
||||||
|
|
||||||
|
/* we don't want to overwrite any referenced layers */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dosnt work here!
|
||||||
|
mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
|
||||||
|
cddm->mvert = mv;
|
||||||
|
*/
|
||||||
|
|
||||||
|
face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
|
||||||
|
if(!face_nors) {
|
||||||
|
calc_face_nors = 1;
|
||||||
|
face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, numFaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
mv = mvert;
|
||||||
|
mf = mface;
|
||||||
|
|
||||||
|
{
|
||||||
|
EdgeHash *edge_hash = BLI_edgehash_new();
|
||||||
|
EdgeHashIterator *edge_iter;
|
||||||
|
int edge_ref_count = 0;
|
||||||
|
int ed_v1, ed_v2; /* use when getting the key */
|
||||||
|
EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity");
|
||||||
|
EdgeFaceRef *edge_ref;
|
||||||
|
float edge_normal[3];
|
||||||
|
|
||||||
|
/* This function adds an edge hash if its not there, and adds the face index */
|
||||||
|
#define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \
|
||||||
|
edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \
|
||||||
|
if (!edge_ref) { \
|
||||||
|
edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \
|
||||||
|
edge_ref->f1=i; \
|
||||||
|
edge_ref->f2=-1; \
|
||||||
|
BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \
|
||||||
|
} else { \
|
||||||
|
edge_ref->f2=i; \
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < numFaces; i++, mf++) {
|
||||||
|
f_no = face_nors[i];
|
||||||
|
|
||||||
|
if(mf->v4) {
|
||||||
|
if(calc_face_nors)
|
||||||
|
normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
|
||||||
|
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2);
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3);
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v4);
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v4, mf->v1);
|
||||||
|
} else {
|
||||||
|
if(calc_face_nors)
|
||||||
|
normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
|
||||||
|
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2);
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3);
|
||||||
|
NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) {
|
||||||
|
/* Get the edge vert indicies, and edge value (the face indicies that use it)*/
|
||||||
|
BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2);
|
||||||
|
edge_ref = BLI_edgehashIterator_getValue(edge_iter);
|
||||||
|
|
||||||
|
if (edge_ref->f2 != -1) {
|
||||||
|
/* We have 2 faces using this edge, calculate the edges normal
|
||||||
|
* using the angle between the 2 faces as a weighting */
|
||||||
|
add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
|
||||||
|
normalize_v3(edge_normal);
|
||||||
|
mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
|
||||||
|
} else {
|
||||||
|
/* only one face attached to that edge */
|
||||||
|
/* an edge without another attached- the weight on this is
|
||||||
|
* undefined, M_PI/2 is 90d in radians and that seems good enough */
|
||||||
|
VECCOPY(edge_normal, face_nors[edge_ref->f1])
|
||||||
|
mul_v3_fl(edge_normal, M_PI/2);
|
||||||
|
}
|
||||||
|
add_v3_v3(temp_nors[ed_v1], edge_normal);
|
||||||
|
add_v3_v3(temp_nors[ed_v2], edge_normal);
|
||||||
|
}
|
||||||
|
BLI_edgehashIterator_free(edge_iter);
|
||||||
|
BLI_edgehash_free(edge_hash, NULL);
|
||||||
|
MEM_freeN(edge_ref_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normalize vertex normals and assign */
|
||||||
|
for(i = 0; i < numVerts; i++, mv++) {
|
||||||
|
if(normalize_v3(temp_nors[i]) == 0.0f) {
|
||||||
|
normal_short_to_float_v3(temp_nors[i], mv->no);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SolidifyModifierData *smd = (SolidifyModifierData*) md;
|
||||||
|
smd->offset = 0.01f;
|
||||||
|
smd->flag = MOD_SOLIDIFY_RIM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
SolidifyModifierData *smd = (SolidifyModifierData*) md;
|
||||||
|
SolidifyModifierData *tsmd = (SolidifyModifierData*) target;
|
||||||
|
tsmd->offset = smd->offset;
|
||||||
|
tsmd->offset_fac = smd->offset_fac;
|
||||||
|
tsmd->crease_inner = smd->crease_inner;
|
||||||
|
tsmd->crease_outer = smd->crease_outer;
|
||||||
|
tsmd->crease_rim = smd->crease_rim;
|
||||||
|
tsmd->flag = smd->flag;
|
||||||
|
strcpy(tsmd->defgrp_name, smd->defgrp_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(ModifierData *md,
|
||||||
|
Object *ob,
|
||||||
|
DerivedMesh *dm,
|
||||||
|
int useRenderParams,
|
||||||
|
int isFinalCalc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
DerivedMesh *result;
|
||||||
|
SolidifyModifierData *smd = (SolidifyModifierData*) md;
|
||||||
|
|
||||||
|
MFace *mf, *mface, *orig_mface;
|
||||||
|
MEdge *ed, *medge, *orig_medge;
|
||||||
|
MVert *mv, *mvert, *orig_mvert;
|
||||||
|
|
||||||
|
int numVerts = dm->getNumVerts(dm);
|
||||||
|
int numEdges = dm->getNumEdges(dm);
|
||||||
|
int numFaces = dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
/* use for edges */
|
||||||
|
int *new_vert_arr= NULL;
|
||||||
|
int newFaces = 0;
|
||||||
|
|
||||||
|
int *new_edge_arr= NULL;
|
||||||
|
int newEdges = 0;
|
||||||
|
|
||||||
|
int *edge_users= NULL;
|
||||||
|
char *edge_order= NULL;
|
||||||
|
|
||||||
|
float (*vert_nors)[3]= NULL;
|
||||||
|
|
||||||
|
float ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
|
||||||
|
float ofs_new= smd->offset - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
|
||||||
|
|
||||||
|
/* weights */
|
||||||
|
MDeformVert *dvert= NULL, *dv= NULL;
|
||||||
|
int defgrp_index= -1;
|
||||||
|
int defgrp_invert = ((smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0);
|
||||||
|
|
||||||
|
defgrp_index= defgroup_name_index(ob, smd->defgrp_name);
|
||||||
|
|
||||||
|
if (defgrp_index >= 0)
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
orig_mface = dm->getFaceArray(dm);
|
||||||
|
orig_medge = dm->getEdgeArray(dm);
|
||||||
|
orig_mvert = dm->getVertArray(dm);
|
||||||
|
|
||||||
|
if(smd->flag & MOD_SOLIDIFY_RIM) {
|
||||||
|
EdgeHash *edgehash = BLI_edgehash_new();
|
||||||
|
EdgeHashIterator *ehi;
|
||||||
|
int v1, v2;
|
||||||
|
int eidx;
|
||||||
|
|
||||||
|
for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) {
|
||||||
|
mv->flag &= ~ME_VERT_TMP_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0, ed=orig_medge; i<numEdges; i++, ed++) {
|
||||||
|
BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_INT_IN_POINTER(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INVALID_UNUSED -1
|
||||||
|
#define INVALID_PAIR -2
|
||||||
|
|
||||||
|
#define ADD_EDGE_USER(_v1, _v2, edge_ord) \
|
||||||
|
eidx= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, _v1, _v2)); \
|
||||||
|
if(edge_users[eidx] == INVALID_UNUSED) { \
|
||||||
|
ed= orig_medge + eidx; \
|
||||||
|
edge_users[eidx]= (_v1 < _v2) == (ed->v1 < ed->v2) ? i:(i+numFaces); \
|
||||||
|
edge_order[eidx]= edge_ord; \
|
||||||
|
} else { \
|
||||||
|
edge_users[eidx]= INVALID_PAIR; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges");
|
||||||
|
edge_order= MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder");
|
||||||
|
memset(edge_users, INVALID_UNUSED, sizeof(int) * numEdges);
|
||||||
|
|
||||||
|
for(i=0, mf=orig_mface; i<numFaces; i++, mf++) {
|
||||||
|
if(mf->v4) {
|
||||||
|
ADD_EDGE_USER(mf->v1, mf->v2, 0);
|
||||||
|
ADD_EDGE_USER(mf->v2, mf->v3, 1);
|
||||||
|
ADD_EDGE_USER(mf->v3, mf->v4, 2);
|
||||||
|
ADD_EDGE_USER(mf->v4, mf->v1, 3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ADD_EDGE_USER(mf->v1, mf->v2, 0);
|
||||||
|
ADD_EDGE_USER(mf->v2, mf->v3, 1);
|
||||||
|
ADD_EDGE_USER(mf->v3, mf->v1, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ADD_EDGE_USER
|
||||||
|
#undef INVALID_UNUSED
|
||||||
|
#undef INVALID_PAIR
|
||||||
|
|
||||||
|
|
||||||
|
new_edge_arr= MEM_callocN(sizeof(int) * numEdges, "solid_mod arr");
|
||||||
|
|
||||||
|
ehi= BLI_edgehashIterator_new(edgehash);
|
||||||
|
for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
|
||||||
|
int eidx= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
|
||||||
|
if(edge_users[eidx] >= 0) {
|
||||||
|
BLI_edgehashIterator_getKey(ehi, &v1, &v2);
|
||||||
|
orig_mvert[v1].flag |= ME_VERT_TMP_TAG;
|
||||||
|
orig_mvert[v2].flag |= ME_VERT_TMP_TAG;
|
||||||
|
new_edge_arr[newFaces]= eidx;
|
||||||
|
newFaces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_edgehashIterator_free(ehi);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
new_vert_arr= MEM_callocN(sizeof(int) * numVerts, "solid_mod new_varr");
|
||||||
|
for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) {
|
||||||
|
if(mv->flag & ME_VERT_TMP_TAG) {
|
||||||
|
new_vert_arr[newEdges] = i;
|
||||||
|
newEdges++;
|
||||||
|
|
||||||
|
mv->flag &= ~ME_VERT_TMP_TAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_edgehash_free(edgehash, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
|
||||||
|
vert_nors= MEM_callocN(sizeof(float) * numVerts * 3, "mod_solid_vno_hq");
|
||||||
|
dm_calc_normal(dm, vert_nors);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, (numFaces * 2) + newFaces);
|
||||||
|
|
||||||
|
mface = result->getFaceArray(result);
|
||||||
|
medge = result->getEdgeArray(result);
|
||||||
|
mvert = result->getVertArray(result);
|
||||||
|
|
||||||
|
DM_copy_face_data(dm, result, 0, 0, numFaces);
|
||||||
|
DM_copy_face_data(dm, result, 0, numFaces, numFaces);
|
||||||
|
|
||||||
|
DM_copy_edge_data(dm, result, 0, 0, numEdges);
|
||||||
|
DM_copy_edge_data(dm, result, 0, numEdges, numEdges);
|
||||||
|
|
||||||
|
DM_copy_vert_data(dm, result, 0, 0, numVerts);
|
||||||
|
DM_copy_vert_data(dm, result, 0, numVerts, numVerts);
|
||||||
|
|
||||||
|
{
|
||||||
|
static int corner_indices[4] = {2, 1, 0, 3};
|
||||||
|
int is_quad;
|
||||||
|
|
||||||
|
for(i=0, mf=mface+numFaces; i<numFaces; i++, mf++) {
|
||||||
|
mf->v1 += numVerts;
|
||||||
|
mf->v2 += numVerts;
|
||||||
|
mf->v3 += numVerts;
|
||||||
|
if(mf->v4)
|
||||||
|
mf->v4 += numVerts;
|
||||||
|
|
||||||
|
/* Flip face normal */
|
||||||
|
{
|
||||||
|
is_quad = mf->v4;
|
||||||
|
SWAP(int, mf->v1, mf->v3);
|
||||||
|
DM_swap_face_data(result, i+numFaces, corner_indices);
|
||||||
|
test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0, ed=medge+numEdges; i<numEdges; i++, ed++) {
|
||||||
|
ed->v1 += numVerts;
|
||||||
|
ed->v2 += numVerts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* note, copied vertex layers dont have flipped normals yet. do this after applying offset */
|
||||||
|
if((smd->flag & MOD_SOLIDIFY_EVEN) == 0) {
|
||||||
|
/* no even thickness, very simple */
|
||||||
|
float scalar_short;
|
||||||
|
float scalar_short_vgroup;
|
||||||
|
|
||||||
|
|
||||||
|
if(ofs_new != 0.0f) {
|
||||||
|
scalar_short= scalar_short_vgroup= ofs_new / 32767.0f;
|
||||||
|
mv= mvert + ((ofs_new >= ofs_orig) ? 0 : numVerts);
|
||||||
|
dv= dvert;
|
||||||
|
for(i=0; i<numVerts; i++, mv++) {
|
||||||
|
if(dv) {
|
||||||
|
if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index));
|
||||||
|
else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index);
|
||||||
|
dv++;
|
||||||
|
}
|
||||||
|
VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ofs_orig != 0.0f) {
|
||||||
|
scalar_short= scalar_short_vgroup= ofs_orig / 32767.0f;
|
||||||
|
mv= mvert + ((ofs_new >= ofs_orig) ? numVerts : 0); /* same as above but swapped, intentional use of 'ofs_new' */
|
||||||
|
dv= dvert;
|
||||||
|
for(i=0; i<numVerts; i++, mv++) {
|
||||||
|
if(dv) {
|
||||||
|
if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index));
|
||||||
|
else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index);
|
||||||
|
dv++;
|
||||||
|
}
|
||||||
|
VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* make a face normal layer if not present */
|
||||||
|
float (*face_nors)[3];
|
||||||
|
int face_nors_calc= 0;
|
||||||
|
|
||||||
|
/* same as EM_solidify() in editmesh_lib.c */
|
||||||
|
float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
|
||||||
|
float *vert_accum= vert_angles + numVerts;
|
||||||
|
float face_angles[4];
|
||||||
|
int i, j, vidx;
|
||||||
|
|
||||||
|
face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
|
||||||
|
if(!face_nors) {
|
||||||
|
face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numFaceData);
|
||||||
|
face_nors_calc= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vert_nors==NULL) {
|
||||||
|
vert_nors= MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno");
|
||||||
|
for(i=0, mv=mvert; i<numVerts; i++, mv++) {
|
||||||
|
normal_short_to_float_v3(vert_nors[i], mv->no);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0, mf=mface; i<numFaces; i++, mf++) {
|
||||||
|
|
||||||
|
/* just added, calc the normal */
|
||||||
|
if(face_nors_calc) {
|
||||||
|
if(mf->v4)
|
||||||
|
normal_quad_v3(face_nors[i], mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
|
||||||
|
else
|
||||||
|
normal_tri_v3(face_nors[i] , mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mf->v4) {
|
||||||
|
angle_quad_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
|
||||||
|
j= 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
angle_tri_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
|
||||||
|
j= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; j>=0; j--) {
|
||||||
|
vidx = *(&mf->v1 + j);
|
||||||
|
vert_accum[vidx] += face_angles[j];
|
||||||
|
vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * face_angles[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vertex group support */
|
||||||
|
if(dvert) {
|
||||||
|
dv= dvert;
|
||||||
|
if(defgrp_invert) {
|
||||||
|
for(i=0; i<numVerts; i++, dv++) {
|
||||||
|
vert_angles[i] *= (1.0f - defvert_find_weight(dv, defgrp_index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(i=0; i<numVerts; i++, dv++) {
|
||||||
|
vert_angles[i] *= defvert_find_weight(dv, defgrp_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ofs_new) {
|
||||||
|
mv= mvert + ((ofs_new >= ofs_orig) ? 0 : numVerts);
|
||||||
|
|
||||||
|
for(i=0; i<numVerts; i++, mv++) {
|
||||||
|
if(vert_accum[i]) { /* zero if unselected */
|
||||||
|
madd_v3_v3fl(mv->co, vert_nors[i], ofs_new * (vert_angles[i] / vert_accum[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ofs_orig) {
|
||||||
|
mv= mvert + ((ofs_new >= ofs_orig) ? numVerts : 0); /* same as above but swapped, intentional use of 'ofs_new' */
|
||||||
|
|
||||||
|
for(i=0; i<numVerts; i++, mv++) {
|
||||||
|
if(vert_accum[i]) { /* zero if unselected */
|
||||||
|
madd_v3_v3fl(mv->co, vert_nors[i], ofs_orig * (vert_angles[i] / vert_accum[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(vert_angles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vert_nors)
|
||||||
|
MEM_freeN(vert_nors);
|
||||||
|
|
||||||
|
/* flip vertex normals for copied verts */
|
||||||
|
mv= mvert + numVerts;
|
||||||
|
for(i=0; i<numVerts; i++, mv++) {
|
||||||
|
mv->no[0]= -mv->no[0];
|
||||||
|
mv->no[1]= -mv->no[1];
|
||||||
|
mv->no[2]= -mv->no[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(smd->flag & MOD_SOLIDIFY_RIM) {
|
||||||
|
|
||||||
|
|
||||||
|
/* bugger, need to re-calculate the normals for the new edge faces.
|
||||||
|
* This could be done in many ways, but probably the quickest way is to calculate the average normals for side faces only.
|
||||||
|
* Then blend them with the normals of the edge verts.
|
||||||
|
*
|
||||||
|
* at the moment its easiest to allocate an entire array for every vertex, even though we only need edge verts - campbell
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SOLIDIFY_SIDE_NORMALS
|
||||||
|
|
||||||
|
#ifdef SOLIDIFY_SIDE_NORMALS
|
||||||
|
/* annoying to allocate these since we only need the edge verts, */
|
||||||
|
float (*edge_vert_nos)[3]= MEM_callocN(sizeof(float) * numVerts * 3, "solidify_edge_nos");
|
||||||
|
float nor[3];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const unsigned char crease_rim= smd->crease_rim * 255.0f;
|
||||||
|
const unsigned char crease_outer= smd->crease_outer * 255.0f;
|
||||||
|
const unsigned char crease_inner= smd->crease_inner * 255.0f;
|
||||||
|
|
||||||
|
const int edge_indices[4][4] = {
|
||||||
|
{1, 0, 0, 1},
|
||||||
|
{2, 1, 1, 2},
|
||||||
|
{3, 2, 2, 3},
|
||||||
|
{0, 3, 3, 0}};
|
||||||
|
|
||||||
|
/* add faces & edges */
|
||||||
|
ed= medge + (numEdges * 2);
|
||||||
|
for(i=0; i<newEdges; i++, ed++) {
|
||||||
|
ed->v1= new_vert_arr[i];
|
||||||
|
ed->v2= new_vert_arr[i] + numVerts;
|
||||||
|
ed->flag |= ME_EDGEDRAW;
|
||||||
|
|
||||||
|
if(crease_rim)
|
||||||
|
ed->crease= crease_rim;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* faces */
|
||||||
|
mf= mface + (numFaces * 2);
|
||||||
|
for(i=0; i<newFaces; i++, mf++) {
|
||||||
|
int eidx= new_edge_arr[i];
|
||||||
|
int fidx= edge_users[eidx];
|
||||||
|
int flip;
|
||||||
|
|
||||||
|
if(fidx >= numFaces) {
|
||||||
|
fidx -= numFaces;
|
||||||
|
flip= 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flip= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ed= medge + eidx;
|
||||||
|
|
||||||
|
/* copy most of the face settings */
|
||||||
|
DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1);
|
||||||
|
|
||||||
|
if(flip) {
|
||||||
|
DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]);
|
||||||
|
|
||||||
|
mf->v1= ed->v1;
|
||||||
|
mf->v2= ed->v2;
|
||||||
|
mf->v3= ed->v2 + numVerts;
|
||||||
|
mf->v4= ed->v1 + numVerts;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]);
|
||||||
|
|
||||||
|
mf->v1= ed->v2;
|
||||||
|
mf->v2= ed->v1;
|
||||||
|
mf->v3= ed->v1 + numVerts;
|
||||||
|
mf->v4= ed->v2 + numVerts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crease_outer)
|
||||||
|
ed->crease= crease_outer;
|
||||||
|
|
||||||
|
if(crease_inner) {
|
||||||
|
medge[numEdges + eidx].crease= crease_inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SOLIDIFY_SIDE_NORMALS
|
||||||
|
normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
|
||||||
|
|
||||||
|
add_v3_v3(edge_vert_nos[ed->v1], nor);
|
||||||
|
add_v3_v3(edge_vert_nos[ed->v2], nor);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SOLIDIFY_SIDE_NORMALS
|
||||||
|
ed= medge + (numEdges * 2);
|
||||||
|
for(i=0; i<newEdges; i++, ed++) {
|
||||||
|
float nor_cpy[3];
|
||||||
|
short *nor_short;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
/* note, only the first vertex (lower half of the index) is calculated */
|
||||||
|
normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]);
|
||||||
|
|
||||||
|
for(j=0; j<2; j++) { /* loop over both verts of the edge */
|
||||||
|
nor_short= mvert[*(&ed->v1 + j)].no;
|
||||||
|
normal_short_to_float_v3(nor, nor_short);
|
||||||
|
add_v3_v3(nor, nor_cpy);
|
||||||
|
normalize_v3(nor);
|
||||||
|
normal_float_to_short_v3(nor_short, nor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(edge_vert_nos);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MEM_freeN(new_vert_arr);
|
||||||
|
MEM_freeN(new_edge_arr);
|
||||||
|
MEM_freeN(edge_users);
|
||||||
|
MEM_freeN(edge_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SOLIDIFY_SIDE_NORMALS
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifierEM(ModifierData *md,
|
||||||
|
Object *ob,
|
||||||
|
EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Solidify = {
|
||||||
|
/* name */ "Solidify",
|
||||||
|
/* structName */ "SolidifyModifierData",
|
||||||
|
/* structSize */ sizeof(SolidifyModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsMapping
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
185
source/blender/modifiers/intern/MOD_subsurf.c
Normal file
185
source/blender/modifiers/intern/MOD_subsurf.c
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||||
|
|
||||||
|
smd->levels = 1;
|
||||||
|
smd->renderLevels = 2;
|
||||||
|
smd->flags |= eSubsurfModifierFlag_SubsurfUv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||||
|
SubsurfModifierData *tsmd = (SubsurfModifierData*) target;
|
||||||
|
|
||||||
|
tsmd->flags = smd->flags;
|
||||||
|
tsmd->levels = smd->levels;
|
||||||
|
tsmd->renderLevels = smd->renderLevels;
|
||||||
|
tsmd->subdivType = smd->subdivType;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||||
|
|
||||||
|
if(smd->mCache) {
|
||||||
|
ccgSubSurf_free(smd->mCache);
|
||||||
|
}
|
||||||
|
if(smd->emCache) {
|
||||||
|
ccgSubSurf_free(smd->emCache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int isDisabled(ModifierData *md, int useRenderParams)
|
||||||
|
{
|
||||||
|
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||||
|
int levels= (useRenderParams)? smd->renderLevels: smd->levels;
|
||||||
|
|
||||||
|
return get_render_subsurf_level(&md->scene->r, levels) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||||
|
DerivedMesh *result;
|
||||||
|
|
||||||
|
result = subsurf_make_derived_from_derived(derivedData, smd,
|
||||||
|
useRenderParams, NULL, isFinalCalc, 0);
|
||||||
|
|
||||||
|
if(useRenderParams || !isFinalCalc) {
|
||||||
|
DerivedMesh *cddm= CDDM_copy(result);
|
||||||
|
result->release(result);
|
||||||
|
result= cddm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||||
|
DerivedMesh *result;
|
||||||
|
|
||||||
|
result = subsurf_make_derived_from_derived(derivedData, smd, 0,
|
||||||
|
NULL, 0, 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Subsurf = {
|
||||||
|
/* name */ "Subsurf",
|
||||||
|
/* structName */ "SubsurfModifierData",
|
||||||
|
/* structSize */ sizeof(SubsurfModifierData),
|
||||||
|
/* type */ eModifierTypeType_Constructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_SupportsMapping
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode
|
||||||
|
| eModifierTypeFlag_AcceptsCVs,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ isDisabled,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
228
source/blender/modifiers/intern/MOD_surface.c
Normal file
228
source/blender/modifiers/intern/MOD_surface.c
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "LOD_decimation.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
/* Surface */
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SurfaceModifierData *surmd = (SurfaceModifierData*) md;
|
||||||
|
|
||||||
|
surmd->bvhtree = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeData(ModifierData *md)
|
||||||
|
{
|
||||||
|
SurfaceModifierData *surmd = (SurfaceModifierData*) md;
|
||||||
|
|
||||||
|
if (surmd)
|
||||||
|
{
|
||||||
|
if(surmd->bvhtree) {
|
||||||
|
free_bvhtree_from_mesh(surmd->bvhtree);
|
||||||
|
MEM_freeN(surmd->bvhtree);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(surmd->dm)
|
||||||
|
surmd->dm->release(surmd->dm);
|
||||||
|
|
||||||
|
if(surmd->x)
|
||||||
|
MEM_freeN(surmd->x);
|
||||||
|
|
||||||
|
if(surmd->v)
|
||||||
|
MEM_freeN(surmd->v);
|
||||||
|
|
||||||
|
surmd->bvhtree = NULL;
|
||||||
|
surmd->dm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
SurfaceModifierData *surmd = (SurfaceModifierData*) md;
|
||||||
|
unsigned int numverts = 0, i = 0;
|
||||||
|
|
||||||
|
if(surmd->dm)
|
||||||
|
surmd->dm->release(surmd->dm);
|
||||||
|
|
||||||
|
/* if possible use/create DerivedMesh */
|
||||||
|
if(derivedData) surmd->dm = CDDM_copy(derivedData);
|
||||||
|
else surmd->dm = get_dm(md->scene, ob, NULL, NULL, NULL, 0);
|
||||||
|
|
||||||
|
if(!ob->pd)
|
||||||
|
{
|
||||||
|
printf("SurfaceModifier deformVerts: Should not happen!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(surmd->dm)
|
||||||
|
{
|
||||||
|
int init = 0;
|
||||||
|
float *vec;
|
||||||
|
MVert *x, *v;
|
||||||
|
|
||||||
|
CDDM_apply_vert_coords(surmd->dm, vertexCos);
|
||||||
|
CDDM_calc_normals(surmd->dm);
|
||||||
|
|
||||||
|
numverts = surmd->dm->getNumVerts ( surmd->dm );
|
||||||
|
|
||||||
|
if(numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL || md->scene->r.cfra != surmd->cfra+1) {
|
||||||
|
if(surmd->x) {
|
||||||
|
MEM_freeN(surmd->x);
|
||||||
|
surmd->x = NULL;
|
||||||
|
}
|
||||||
|
if(surmd->v) {
|
||||||
|
MEM_freeN(surmd->v);
|
||||||
|
surmd->v = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
surmd->x = MEM_callocN(numverts * sizeof(MVert), "MVert");
|
||||||
|
surmd->v = MEM_callocN(numverts * sizeof(MVert), "MVert");
|
||||||
|
|
||||||
|
surmd->numverts = numverts;
|
||||||
|
|
||||||
|
init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert to global coordinates and calculate velocity */
|
||||||
|
for(i = 0, x = surmd->x, v = surmd->v; i<numverts; i++, x++, v++) {
|
||||||
|
vec = CDDM_get_vert(surmd->dm, i)->co;
|
||||||
|
mul_m4_v3(ob->obmat, vec);
|
||||||
|
|
||||||
|
if(init)
|
||||||
|
v->co[0] = v->co[1] = v->co[2] = 0.0f;
|
||||||
|
else
|
||||||
|
sub_v3_v3v3(v->co, vec, x->co);
|
||||||
|
|
||||||
|
copy_v3_v3(x->co, vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
surmd->cfra = md->scene->r.cfra;
|
||||||
|
|
||||||
|
if(surmd->bvhtree)
|
||||||
|
free_bvhtree_from_mesh(surmd->bvhtree);
|
||||||
|
else
|
||||||
|
surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
|
||||||
|
|
||||||
|
if(surmd->dm->getNumFaces(surmd->dm))
|
||||||
|
bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
|
||||||
|
else
|
||||||
|
bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Surface = {
|
||||||
|
/* name */ "Surface",
|
||||||
|
/* structName */ "SurfaceModifierData",
|
||||||
|
/* structSize */ sizeof(SurfaceModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_NoUserAdd,
|
||||||
|
|
||||||
|
/* copyData */ 0,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ 0,
|
||||||
|
/* freeData */ freeData,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ 0,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ 0,
|
||||||
|
/* foreachIDLink */ 0,
|
||||||
|
};
|
||||||
173
source/blender/modifiers/intern/MOD_util.c
Normal file
173
source/blender/modifiers/intern/MOD_util.c
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* $Id: CMP_node.h 14061 2008-03-11 14:40:27Z blendix $
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful;
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation;
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The Original Code is: all of this file.
|
||||||
|
*
|
||||||
|
* Contributor(s): Ben Batt
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DNA_modifier_types.h"
|
||||||
|
#include "DNA_customdata_types.h"
|
||||||
|
#include "DNA_texture_types.h"
|
||||||
|
#include "DNA_object_types.h"
|
||||||
|
#include "DNA_mesh_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
#include "BKE_customdata.h"
|
||||||
|
#include "BKE_DerivedMesh.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "BKE_utildefines.h"
|
||||||
|
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
void get_texture_value(Tex *texture, float *tex_co, TexResult *texres)
|
||||||
|
{
|
||||||
|
int result_type;
|
||||||
|
|
||||||
|
result_type = multitex_ext(texture, tex_co, NULL, NULL, 0, texres);
|
||||||
|
|
||||||
|
/* if the texture gave an RGB value, we assume it didn't give a valid
|
||||||
|
* intensity, so calculate one (formula from do_material_tex).
|
||||||
|
* if the texture didn't give an RGB value, copy the intensity across
|
||||||
|
*/
|
||||||
|
if(result_type & TEX_RGB)
|
||||||
|
texres->tin = (0.35f * texres->tr + 0.45f * texres->tg
|
||||||
|
+ 0.2f * texres->tb);
|
||||||
|
else
|
||||||
|
texres->tr = texres->tg = texres->tb = texres->tin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
|
||||||
|
{
|
||||||
|
while((md=md->next) && md->type==eModifierType_Armature) {
|
||||||
|
ArmatureModifierData *amd = (ArmatureModifierData*) md;
|
||||||
|
if(amd->multi && amd->prevCos==NULL)
|
||||||
|
amd->prevCos= MEM_dupallocN(vertexCos);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* lattice/mesh modifier too */
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate_layer_name(const CustomData *data, int type, char *name, char *outname)
|
||||||
|
{
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
/* if a layer name was given, try to find that layer */
|
||||||
|
if(name[0])
|
||||||
|
index = CustomData_get_named_layer_index(data, CD_MTFACE, name);
|
||||||
|
|
||||||
|
if(index < 0) {
|
||||||
|
/* either no layer was specified, or the layer we want has been
|
||||||
|
* deleted, so assign the active layer to name
|
||||||
|
*/
|
||||||
|
index = CustomData_get_active_layer_index(data, CD_MTFACE);
|
||||||
|
strcpy(outname, data->layers[index].name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(outname, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */
|
||||||
|
DerivedMesh *get_cddm(struct Scene *scene, Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3])
|
||||||
|
{
|
||||||
|
if(dm && dm->type == DM_TYPE_CDDM)
|
||||||
|
return dm;
|
||||||
|
|
||||||
|
if(!dm) {
|
||||||
|
dm= get_dm(scene, ob, em, dm, vertexCos, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dm= CDDM_copy(dm);
|
||||||
|
CDDM_apply_vert_coords(dm, vertexCos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dm)
|
||||||
|
CDDM_calc_normals(dm);
|
||||||
|
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int is_last_displist(Object *ob)
|
||||||
|
{
|
||||||
|
Curve *cu = ob->data;
|
||||||
|
static int curvecount=0, totcurve=0;
|
||||||
|
|
||||||
|
if(curvecount == 0){
|
||||||
|
DispList *dl;
|
||||||
|
|
||||||
|
totcurve = 0;
|
||||||
|
for(dl=cu->disp.first; dl; dl=dl->next)
|
||||||
|
totcurve++;
|
||||||
|
}
|
||||||
|
|
||||||
|
curvecount++;
|
||||||
|
|
||||||
|
if(curvecount == totcurve){
|
||||||
|
curvecount = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns a derived mesh if dm == NULL, for deforming modifiers that need it */
|
||||||
|
DerivedMesh *get_dm(struct Scene *scene, Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco)
|
||||||
|
{
|
||||||
|
if(dm)
|
||||||
|
return dm;
|
||||||
|
|
||||||
|
if(ob->type==OB_MESH) {
|
||||||
|
if(em) dm= CDDM_from_editmesh(em, ob->data);
|
||||||
|
else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob);
|
||||||
|
|
||||||
|
if(vertexCos) {
|
||||||
|
CDDM_apply_vert_coords(dm, vertexCos);
|
||||||
|
//CDDM_calc_normals(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(orco)
|
||||||
|
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
|
||||||
|
}
|
||||||
|
else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) {
|
||||||
|
if(is_last_displist(ob)) {
|
||||||
|
dm= CDDM_from_curve(ob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
45
source/blender/modifiers/intern/MOD_util.h
Normal file
45
source/blender/modifiers/intern/MOD_util.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful;
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation;
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Contributor(s): Ben Batt
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MOD_UTIL_H
|
||||||
|
#define MOD_UTIL_H
|
||||||
|
|
||||||
|
struct Tex;
|
||||||
|
struct TexResult;
|
||||||
|
struct CustomData;
|
||||||
|
struct DerivedMesh;
|
||||||
|
struct Object;
|
||||||
|
struct Scene;
|
||||||
|
struct EditMesh;
|
||||||
|
struct ModifierData;
|
||||||
|
|
||||||
|
void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *texres);
|
||||||
|
void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]);
|
||||||
|
void validate_layer_name(const struct CustomData *data, int type, char *name, char *outname);
|
||||||
|
struct DerivedMesh *get_cddm(struct Scene *scene, struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]);
|
||||||
|
struct DerivedMesh *get_dm(struct Scene *scene, struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco);
|
||||||
|
#endif /* MOD_UTIL_H */
|
||||||
491
source/blender/modifiers/intern/MOD_uvproject.c
Normal file
491
source/blender/modifiers/intern/MOD_uvproject.c
Normal file
@@ -0,0 +1,491 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* UVProject */
|
||||||
|
/* UV Project modifier: Generates UVs projected from an object
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
UVProjectModifierData *umd = (UVProjectModifierData*) md;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
|
||||||
|
umd->projectors[i] = NULL;
|
||||||
|
umd->image = NULL;
|
||||||
|
umd->flags = 0;
|
||||||
|
umd->num_projectors = 1;
|
||||||
|
umd->aspectx = umd->aspecty = 1.0f;
|
||||||
|
umd->scalex = umd->scaley = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
UVProjectModifierData *umd = (UVProjectModifierData*) md;
|
||||||
|
UVProjectModifierData *tumd = (UVProjectModifierData*) target;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
|
||||||
|
tumd->projectors[i] = umd->projectors[i];
|
||||||
|
tumd->image = umd->image;
|
||||||
|
tumd->flags = umd->flags;
|
||||||
|
tumd->num_projectors = umd->num_projectors;
|
||||||
|
tumd->aspectx = umd->aspectx;
|
||||||
|
tumd->aspecty = umd->aspecty;
|
||||||
|
tumd->scalex = umd->scalex;
|
||||||
|
tumd->scaley = umd->scaley;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
/* ask for UV coordinates */
|
||||||
|
dataMask |= (1 << CD_MTFACE);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(ModifierData *md, Object *ob,
|
||||||
|
ObjectWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
UVProjectModifierData *umd = (UVProjectModifierData*) md;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
|
||||||
|
walk(userData, ob, &umd->projectors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachIDLink(ModifierData *md, Object *ob,
|
||||||
|
IDWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
UVProjectModifierData *umd = (UVProjectModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, (ID **)&umd->image);
|
||||||
|
|
||||||
|
foreachObjectLink(md, ob, (ObjectWalkFunc)walk,
|
||||||
|
userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(ModifierData *md,
|
||||||
|
DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
|
||||||
|
{
|
||||||
|
UVProjectModifierData *umd = (UVProjectModifierData*) md;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < umd->num_projectors; ++i) {
|
||||||
|
if(umd->projectors[i]) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, umd->projectors[i]);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode,
|
||||||
|
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "UV Project Modifier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct Projector {
|
||||||
|
Object *ob; /* object this projector is derived from */
|
||||||
|
float projmat[4][4]; /* projection matrix */
|
||||||
|
float normal[3]; /* projector normal in world space */
|
||||||
|
void *uci; /* optional uv-project info (panorama projection) */
|
||||||
|
} Projector;
|
||||||
|
|
||||||
|
static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
||||||
|
Object *ob, DerivedMesh *dm)
|
||||||
|
{
|
||||||
|
float (*coords)[3], (*co)[3];
|
||||||
|
MTFace *tface;
|
||||||
|
int i, numVerts, numFaces;
|
||||||
|
Image *image = umd->image;
|
||||||
|
MFace *mface, *mf;
|
||||||
|
int override_image = ((umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0);
|
||||||
|
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
|
||||||
|
int num_projectors = 0;
|
||||||
|
float aspect;
|
||||||
|
char uvname[32];
|
||||||
|
float aspx= umd->aspectx ? umd->aspectx : 1.0f;
|
||||||
|
float aspy= umd->aspecty ? umd->aspecty : 1.0f;
|
||||||
|
float scax= umd->scalex ? umd->scalex : 1.0f;
|
||||||
|
float scay= umd->scaley ? umd->scaley : 1.0f;
|
||||||
|
int free_uci= 0;
|
||||||
|
|
||||||
|
aspect = aspx / aspy;
|
||||||
|
|
||||||
|
for(i = 0; i < umd->num_projectors; ++i)
|
||||||
|
if(umd->projectors[i])
|
||||||
|
projectors[num_projectors++].ob = umd->projectors[i];
|
||||||
|
|
||||||
|
if(num_projectors == 0) return dm;
|
||||||
|
|
||||||
|
/* make sure there are UV layers available */
|
||||||
|
|
||||||
|
if(!CustomData_has_layer(&dm->faceData, CD_MTFACE)) return dm;
|
||||||
|
|
||||||
|
/* make sure we're using an existing layer */
|
||||||
|
validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
|
||||||
|
|
||||||
|
/* calculate a projection matrix and normal for each projector */
|
||||||
|
for(i = 0; i < num_projectors; ++i) {
|
||||||
|
float tmpmat[4][4];
|
||||||
|
float offsetmat[4][4];
|
||||||
|
Camera *cam = NULL;
|
||||||
|
/* calculate projection matrix */
|
||||||
|
invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
|
||||||
|
|
||||||
|
projectors[i].uci= NULL;
|
||||||
|
|
||||||
|
if(projectors[i].ob->type == OB_CAMERA) {
|
||||||
|
cam = (Camera *)projectors[i].ob->data;
|
||||||
|
|
||||||
|
if(cam->flag & CAM_PANORAMA) {
|
||||||
|
projectors[i].uci= project_camera_info(projectors[i].ob, NULL, aspx, aspy);
|
||||||
|
free_uci= 1;
|
||||||
|
}
|
||||||
|
else if(cam->type == CAM_PERSP) {
|
||||||
|
float perspmat[4][4];
|
||||||
|
float xmax;
|
||||||
|
float xmin;
|
||||||
|
float ymax;
|
||||||
|
float ymin;
|
||||||
|
float pixsize = cam->clipsta * 32.0 / cam->lens;
|
||||||
|
|
||||||
|
if(aspect > 1.0f) {
|
||||||
|
xmax = 0.5f * pixsize;
|
||||||
|
ymax = xmax / aspect;
|
||||||
|
} else {
|
||||||
|
ymax = 0.5f * pixsize;
|
||||||
|
xmax = ymax * aspect;
|
||||||
|
}
|
||||||
|
xmin = -xmax;
|
||||||
|
ymin = -ymax;
|
||||||
|
|
||||||
|
perspective_m4( perspmat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend);
|
||||||
|
mul_m4_m4m4(tmpmat, projectors[i].projmat, perspmat);
|
||||||
|
} else if(cam->type == CAM_ORTHO) {
|
||||||
|
float orthomat[4][4];
|
||||||
|
float xmax;
|
||||||
|
float xmin;
|
||||||
|
float ymax;
|
||||||
|
float ymin;
|
||||||
|
|
||||||
|
if(aspect > 1.0f) {
|
||||||
|
xmax = 0.5f * cam->ortho_scale;
|
||||||
|
ymax = xmax / aspect;
|
||||||
|
} else {
|
||||||
|
ymax = 0.5f * cam->ortho_scale;
|
||||||
|
xmax = ymax * aspect;
|
||||||
|
}
|
||||||
|
xmin = -xmax;
|
||||||
|
ymin = -ymax;
|
||||||
|
|
||||||
|
orthographic_m4( orthomat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend);
|
||||||
|
mul_m4_m4m4(tmpmat, projectors[i].projmat, orthomat);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copy_m4_m4(tmpmat, projectors[i].projmat);
|
||||||
|
}
|
||||||
|
|
||||||
|
unit_m4(offsetmat);
|
||||||
|
mul_mat3_m4_fl(offsetmat, 0.5);
|
||||||
|
offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
|
||||||
|
|
||||||
|
if (cam) {
|
||||||
|
if (aspx == aspy) {
|
||||||
|
offsetmat[3][0] -= cam->shiftx;
|
||||||
|
offsetmat[3][1] -= cam->shifty;
|
||||||
|
} else if (aspx < aspy) {
|
||||||
|
offsetmat[3][0] -=(cam->shiftx * aspy/aspx);
|
||||||
|
offsetmat[3][1] -= cam->shifty;
|
||||||
|
} else {
|
||||||
|
offsetmat[3][0] -= cam->shiftx;
|
||||||
|
offsetmat[3][1] -=(cam->shifty * aspx/aspy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mul_m4_m4m4(projectors[i].projmat, tmpmat, offsetmat);
|
||||||
|
|
||||||
|
/* calculate worldspace projector normal (for best projector test) */
|
||||||
|
projectors[i].normal[0] = 0;
|
||||||
|
projectors[i].normal[1] = 0;
|
||||||
|
projectors[i].normal[2] = 1;
|
||||||
|
mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure we are not modifying the original UV layer */
|
||||||
|
tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
|
||||||
|
CD_MTFACE, uvname);
|
||||||
|
|
||||||
|
|
||||||
|
numVerts = dm->getNumVerts(dm);
|
||||||
|
|
||||||
|
coords = MEM_callocN(sizeof(*coords) * numVerts,
|
||||||
|
"uvprojectModifier_do coords");
|
||||||
|
dm->getVertCos(dm, coords);
|
||||||
|
|
||||||
|
/* convert coords to world space */
|
||||||
|
for(i = 0, co = coords; i < numVerts; ++i, ++co)
|
||||||
|
mul_m4_v3(ob->obmat, *co);
|
||||||
|
|
||||||
|
/* if only one projector, project coords to UVs */
|
||||||
|
if(num_projectors == 1 && projectors[0].uci==NULL)
|
||||||
|
for(i = 0, co = coords; i < numVerts; ++i, ++co)
|
||||||
|
mul_project_m4_v4(projectors[0].projmat, *co);
|
||||||
|
|
||||||
|
mface = dm->getFaceArray(dm);
|
||||||
|
numFaces = dm->getNumFaces(dm);
|
||||||
|
|
||||||
|
/* apply coords as UVs, and apply image if tfaces are new */
|
||||||
|
for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) {
|
||||||
|
if(override_image || !image || tface->tpage == image) {
|
||||||
|
if(num_projectors == 1) {
|
||||||
|
if(projectors[0].uci) {
|
||||||
|
project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci);
|
||||||
|
project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci);
|
||||||
|
project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci);
|
||||||
|
if(mf->v3)
|
||||||
|
project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci);
|
||||||
|
|
||||||
|
if(scax != 1.0f) {
|
||||||
|
tface->uv[0][0] = ((tface->uv[0][0] - 0.5f) * scax) + 0.5f;
|
||||||
|
tface->uv[1][0] = ((tface->uv[1][0] - 0.5f) * scax) + 0.5f;
|
||||||
|
tface->uv[2][0] = ((tface->uv[2][0] - 0.5f) * scax) + 0.5f;
|
||||||
|
if(mf->v3)
|
||||||
|
tface->uv[3][0] = ((tface->uv[3][0] - 0.5f) * scax) + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scay != 1.0f) {
|
||||||
|
tface->uv[0][1] = ((tface->uv[0][1] - 0.5f) * scay) + 0.5f;
|
||||||
|
tface->uv[1][1] = ((tface->uv[1][1] - 0.5f) * scay) + 0.5f;
|
||||||
|
tface->uv[2][1] = ((tface->uv[2][1] - 0.5f) * scay) + 0.5f;
|
||||||
|
if(mf->v3)
|
||||||
|
tface->uv[3][1] = ((tface->uv[3][1] - 0.5f) * scay) + 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* apply transformed coords as UVs */
|
||||||
|
tface->uv[0][0] = coords[mf->v1][0];
|
||||||
|
tface->uv[0][1] = coords[mf->v1][1];
|
||||||
|
tface->uv[1][0] = coords[mf->v2][0];
|
||||||
|
tface->uv[1][1] = coords[mf->v2][1];
|
||||||
|
tface->uv[2][0] = coords[mf->v3][0];
|
||||||
|
tface->uv[2][1] = coords[mf->v3][1];
|
||||||
|
if(mf->v4) {
|
||||||
|
tface->uv[3][0] = coords[mf->v4][0];
|
||||||
|
tface->uv[3][1] = coords[mf->v4][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* multiple projectors, select the closest to face normal
|
||||||
|
* direction
|
||||||
|
*/
|
||||||
|
float co1[3], co2[3], co3[3], co4[3];
|
||||||
|
float face_no[3];
|
||||||
|
int j;
|
||||||
|
Projector *best_projector;
|
||||||
|
float best_dot;
|
||||||
|
|
||||||
|
VECCOPY(co1, coords[mf->v1]);
|
||||||
|
VECCOPY(co2, coords[mf->v2]);
|
||||||
|
VECCOPY(co3, coords[mf->v3]);
|
||||||
|
|
||||||
|
/* get the untransformed face normal */
|
||||||
|
if(mf->v4) {
|
||||||
|
VECCOPY(co4, coords[mf->v4]);
|
||||||
|
normal_quad_v3( face_no,co1, co2, co3, co4);
|
||||||
|
} else {
|
||||||
|
normal_tri_v3( face_no,co1, co2, co3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the projector which the face points at most directly
|
||||||
|
* (projector normal with largest dot product is best)
|
||||||
|
*/
|
||||||
|
best_dot = dot_v3v3(projectors[0].normal, face_no);
|
||||||
|
best_projector = &projectors[0];
|
||||||
|
|
||||||
|
for(j = 1; j < num_projectors; ++j) {
|
||||||
|
float tmp_dot = dot_v3v3(projectors[j].normal,
|
||||||
|
face_no);
|
||||||
|
if(tmp_dot > best_dot) {
|
||||||
|
best_dot = tmp_dot;
|
||||||
|
best_projector = &projectors[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(best_projector->uci) {
|
||||||
|
project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci);
|
||||||
|
project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci);
|
||||||
|
project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci);
|
||||||
|
if(mf->v3)
|
||||||
|
project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mul_project_m4_v4(best_projector->projmat, co1);
|
||||||
|
mul_project_m4_v4(best_projector->projmat, co2);
|
||||||
|
mul_project_m4_v4(best_projector->projmat, co3);
|
||||||
|
if(mf->v4)
|
||||||
|
mul_project_m4_v4(best_projector->projmat, co4);
|
||||||
|
|
||||||
|
/* apply transformed coords as UVs */
|
||||||
|
tface->uv[0][0] = co1[0];
|
||||||
|
tface->uv[0][1] = co1[1];
|
||||||
|
tface->uv[1][0] = co2[0];
|
||||||
|
tface->uv[1][1] = co2[1];
|
||||||
|
tface->uv[2][0] = co3[0];
|
||||||
|
tface->uv[2][1] = co3[1];
|
||||||
|
if(mf->v4) {
|
||||||
|
tface->uv[3][0] = co4[0];
|
||||||
|
tface->uv[3][1] = co4[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(override_image) {
|
||||||
|
tface->mode = TF_TEX;
|
||||||
|
tface->tpage = image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(coords);
|
||||||
|
|
||||||
|
if(free_uci) {
|
||||||
|
int j;
|
||||||
|
for(j = 0; j < num_projectors; ++j) {
|
||||||
|
if(projectors[j].uci) {
|
||||||
|
MEM_freeN(projectors[j].uci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifier(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *result;
|
||||||
|
UVProjectModifierData *umd = (UVProjectModifierData*) md;
|
||||||
|
|
||||||
|
result = uvprojectModifier_do(umd, ob, derivedData);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DerivedMesh *applyModifierEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData)
|
||||||
|
{
|
||||||
|
return applyModifier(md, ob, derivedData, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_UVProject = {
|
||||||
|
/* name */ "UVProject",
|
||||||
|
/* structName */ "UVProjectModifierData",
|
||||||
|
/* structSize */ sizeof(UVProjectModifierData),
|
||||||
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||||
|
| eModifierTypeFlag_SupportsMapping
|
||||||
|
| eModifierTypeFlag_SupportsEditmode
|
||||||
|
| eModifierTypeFlag_EnableInEditmode,
|
||||||
|
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ 0,
|
||||||
|
/* deformVertsEM */ 0,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ applyModifier,
|
||||||
|
/* applyModifierEM */ applyModifierEM,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ 0,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ foreachIDLink,
|
||||||
|
};
|
||||||
497
source/blender/modifiers/intern/MOD_wave.c
Normal file
497
source/blender/modifiers/intern/MOD_wave.c
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
/*
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Daniel Dunbar
|
||||||
|
* Ton Roosendaal,
|
||||||
|
* Ben Batt,
|
||||||
|
* Brecht Van Lommel,
|
||||||
|
* Campbell Barton
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "float.h"
|
||||||
|
|
||||||
|
#include "BLI_kdtree.h"
|
||||||
|
#include "BLI_rand.h"
|
||||||
|
#include "BLI_uvproject.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
|
#include "DNA_camera_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
#include "DNA_material_types.h"
|
||||||
|
#include "DNA_object_fluidsim.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_bmesh.h"
|
||||||
|
#include "BKE_booleanops.h"
|
||||||
|
#include "BKE_cloth.h"
|
||||||
|
#include "BKE_cdderivedmesh.h"
|
||||||
|
#include "BKE_displist.h"
|
||||||
|
#include "BKE_fluidsim.h"
|
||||||
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_multires.h"
|
||||||
|
#include "BKE_key.h"
|
||||||
|
#include "BKE_lattice.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_object.h"
|
||||||
|
#include "BKE_paint.h"
|
||||||
|
#include "BKE_particle.h"
|
||||||
|
#include "BKE_pointcache.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
|
#include "BKE_smoke.h"
|
||||||
|
#include "BKE_softbody.h"
|
||||||
|
#include "BKE_subsurf.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
|
#include "depsgraph_private.h"
|
||||||
|
#include "BKE_deform.h"
|
||||||
|
#include "BKE_shrinkwrap.h"
|
||||||
|
|
||||||
|
#include "CCGSubSurf.h"
|
||||||
|
|
||||||
|
#include "RE_shader_ext.h"
|
||||||
|
|
||||||
|
#include "MOD_modifiertypes.h"
|
||||||
|
#include "MOD_util.h"
|
||||||
|
|
||||||
|
static void initData(ModifierData *md)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq
|
||||||
|
|
||||||
|
wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL
|
||||||
|
| MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z);
|
||||||
|
|
||||||
|
wmd->objectcenter = NULL;
|
||||||
|
wmd->texture = NULL;
|
||||||
|
wmd->map_object = NULL;
|
||||||
|
wmd->height= 0.5f;
|
||||||
|
wmd->width= 1.5f;
|
||||||
|
wmd->speed= 0.25f;
|
||||||
|
wmd->narrow= 1.5f;
|
||||||
|
wmd->lifetime= 0.0f;
|
||||||
|
wmd->damp= 10.0f;
|
||||||
|
wmd->falloff= 0.0f;
|
||||||
|
wmd->texmapping = MOD_WAV_MAP_LOCAL;
|
||||||
|
wmd->defgrp_name[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyData(ModifierData *md, ModifierData *target)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData*) md;
|
||||||
|
WaveModifierData *twmd = (WaveModifierData*) target;
|
||||||
|
|
||||||
|
twmd->damp = wmd->damp;
|
||||||
|
twmd->flag = wmd->flag;
|
||||||
|
twmd->height = wmd->height;
|
||||||
|
twmd->lifetime = wmd->lifetime;
|
||||||
|
twmd->narrow = wmd->narrow;
|
||||||
|
twmd->speed = wmd->speed;
|
||||||
|
twmd->startx = wmd->startx;
|
||||||
|
twmd->starty = wmd->starty;
|
||||||
|
twmd->timeoffs = wmd->timeoffs;
|
||||||
|
twmd->width = wmd->width;
|
||||||
|
twmd->falloff = wmd->falloff;
|
||||||
|
twmd->objectcenter = wmd->objectcenter;
|
||||||
|
twmd->texture = wmd->texture;
|
||||||
|
twmd->map_object = wmd->map_object;
|
||||||
|
twmd->texmapping = wmd->texmapping;
|
||||||
|
strncpy(twmd->defgrp_name, wmd->defgrp_name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dependsOnTime(ModifierData *md)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachObjectLink(
|
||||||
|
ModifierData *md, Object *ob,
|
||||||
|
ObjectWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, &wmd->objectcenter);
|
||||||
|
walk(userData, ob, &wmd->map_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreachIDLink(ModifierData *md, Object *ob,
|
||||||
|
IDWalkFunc walk, void *userData)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData*) md;
|
||||||
|
|
||||||
|
walk(userData, ob, (ID **)&wmd->texture);
|
||||||
|
|
||||||
|
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDepgraph(
|
||||||
|
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
|
||||||
|
DagNode *obNode)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData*) md;
|
||||||
|
|
||||||
|
if(wmd->objectcenter) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, wmd->objectcenter);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
|
||||||
|
"Wave Modifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wmd->map_object) {
|
||||||
|
DagNode *curNode = dag_get_node(forest, wmd->map_object);
|
||||||
|
|
||||||
|
dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
|
||||||
|
"Wave Modifer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData *)md;
|
||||||
|
CustomDataMask dataMask = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* ask for UV coordinates if we need them */
|
||||||
|
if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV)
|
||||||
|
dataMask |= (1 << CD_MTFACE);
|
||||||
|
|
||||||
|
/* ask for vertexgroups if we need them */
|
||||||
|
if(wmd->defgrp_name[0])
|
||||||
|
dataMask |= (1 << CD_MDEFORMVERT);
|
||||||
|
|
||||||
|
return dataMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
|
||||||
|
DerivedMesh *dm,
|
||||||
|
float (*co)[3], float (*texco)[3],
|
||||||
|
int numVerts)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int texmapping = wmd->texmapping;
|
||||||
|
|
||||||
|
if(texmapping == MOD_WAV_MAP_OBJECT) {
|
||||||
|
if(wmd->map_object)
|
||||||
|
invert_m4_m4(wmd->map_object->imat, wmd->map_object->obmat);
|
||||||
|
else /* if there is no map object, default to local */
|
||||||
|
texmapping = MOD_WAV_MAP_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UVs need special handling, since they come from faces */
|
||||||
|
if(texmapping == MOD_WAV_MAP_UV) {
|
||||||
|
if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
|
||||||
|
MFace *mface = dm->getFaceArray(dm);
|
||||||
|
MFace *mf;
|
||||||
|
char *done = MEM_callocN(sizeof(*done) * numVerts,
|
||||||
|
"get_texture_coords done");
|
||||||
|
int numFaces = dm->getNumFaces(dm);
|
||||||
|
char uvname[32];
|
||||||
|
MTFace *tf;
|
||||||
|
|
||||||
|
validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
|
||||||
|
tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
|
||||||
|
|
||||||
|
/* verts are given the UV from the first face that uses them */
|
||||||
|
for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
|
||||||
|
if(!done[mf->v1]) {
|
||||||
|
texco[mf->v1][0] = tf->uv[0][0];
|
||||||
|
texco[mf->v1][1] = tf->uv[0][1];
|
||||||
|
texco[mf->v1][2] = 0;
|
||||||
|
done[mf->v1] = 1;
|
||||||
|
}
|
||||||
|
if(!done[mf->v2]) {
|
||||||
|
texco[mf->v2][0] = tf->uv[1][0];
|
||||||
|
texco[mf->v2][1] = tf->uv[1][1];
|
||||||
|
texco[mf->v2][2] = 0;
|
||||||
|
done[mf->v2] = 1;
|
||||||
|
}
|
||||||
|
if(!done[mf->v3]) {
|
||||||
|
texco[mf->v3][0] = tf->uv[2][0];
|
||||||
|
texco[mf->v3][1] = tf->uv[2][1];
|
||||||
|
texco[mf->v3][2] = 0;
|
||||||
|
done[mf->v3] = 1;
|
||||||
|
}
|
||||||
|
if(!done[mf->v4]) {
|
||||||
|
texco[mf->v4][0] = tf->uv[3][0];
|
||||||
|
texco[mf->v4][1] = tf->uv[3][1];
|
||||||
|
texco[mf->v4][2] = 0;
|
||||||
|
done[mf->v4] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remap UVs from [0, 1] to [-1, 1] */
|
||||||
|
for(i = 0; i < numVerts; ++i) {
|
||||||
|
texco[i][0] = texco[i][0] * 2 - 1;
|
||||||
|
texco[i][1] = texco[i][1] * 2 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(done);
|
||||||
|
return;
|
||||||
|
} else /* if there are no UVs, default to local */
|
||||||
|
texmapping = MOD_WAV_MAP_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < numVerts; ++i, ++co, ++texco) {
|
||||||
|
switch(texmapping) {
|
||||||
|
case MOD_WAV_MAP_LOCAL:
|
||||||
|
VECCOPY(*texco, *co);
|
||||||
|
break;
|
||||||
|
case MOD_WAV_MAP_GLOBAL:
|
||||||
|
VECCOPY(*texco, *co);
|
||||||
|
mul_m4_v3(ob->obmat, *texco);
|
||||||
|
break;
|
||||||
|
case MOD_WAV_MAP_OBJECT:
|
||||||
|
VECCOPY(*texco, *co);
|
||||||
|
mul_m4_v3(ob->obmat, *texco);
|
||||||
|
mul_m4_v3(wmd->map_object->imat, *texco);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void waveModifier_do(WaveModifierData *md,
|
||||||
|
Scene *scene, Object *ob, DerivedMesh *dm,
|
||||||
|
float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
WaveModifierData *wmd = (WaveModifierData*) md;
|
||||||
|
MVert *mvert = NULL;
|
||||||
|
MDeformVert *dvert = NULL;
|
||||||
|
int defgrp_index;
|
||||||
|
float ctime = bsystem_time(scene, ob, (float)scene->r.cfra, 0.0);
|
||||||
|
float minfac =
|
||||||
|
(float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
|
||||||
|
float lifefac = wmd->height;
|
||||||
|
float (*tex_co)[3] = NULL;
|
||||||
|
|
||||||
|
if(wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH)
|
||||||
|
mvert = dm->getVertArray(dm);
|
||||||
|
|
||||||
|
if(wmd->objectcenter){
|
||||||
|
float mat[4][4];
|
||||||
|
/* get the control object's location in local coordinates */
|
||||||
|
invert_m4_m4(ob->imat, ob->obmat);
|
||||||
|
mul_m4_m4m4(mat, wmd->objectcenter->obmat, ob->imat);
|
||||||
|
|
||||||
|
wmd->startx = mat[3][0];
|
||||||
|
wmd->starty = mat[3][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the index of the deform group */
|
||||||
|
defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
|
||||||
|
|
||||||
|
if(defgrp_index >= 0){
|
||||||
|
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wmd->damp == 0) wmd->damp = 10.0f;
|
||||||
|
|
||||||
|
if(wmd->lifetime != 0.0) {
|
||||||
|
float x = ctime - wmd->timeoffs;
|
||||||
|
|
||||||
|
if(x > wmd->lifetime) {
|
||||||
|
lifefac = x - wmd->lifetime;
|
||||||
|
|
||||||
|
if(lifefac > wmd->damp) lifefac = 0.0;
|
||||||
|
else lifefac =
|
||||||
|
(float)(wmd->height * (1.0 - sqrt(lifefac / wmd->damp)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wmd->texture) {
|
||||||
|
tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts,
|
||||||
|
"waveModifier_do tex_co");
|
||||||
|
wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lifefac != 0.0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < numVerts; i++) {
|
||||||
|
float *co = vertexCos[i];
|
||||||
|
float x = co[0] - wmd->startx;
|
||||||
|
float y = co[1] - wmd->starty;
|
||||||
|
float amplit= 0.0f;
|
||||||
|
float dist = 0.0f;
|
||||||
|
float falloff_fac = 0.0f;
|
||||||
|
TexResult texres;
|
||||||
|
MDeformWeight *def_weight = NULL;
|
||||||
|
|
||||||
|
/* get weights */
|
||||||
|
if(dvert) {
|
||||||
|
int j;
|
||||||
|
for(j = 0; j < dvert[i].totweight; ++j) {
|
||||||
|
if(dvert[i].dw[j].def_nr == defgrp_index) {
|
||||||
|
def_weight = &dvert[i].dw[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if this vert isn't in the vgroup, don't deform it */
|
||||||
|
if(!def_weight) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wmd->texture) {
|
||||||
|
texres.nor = NULL;
|
||||||
|
get_texture_value(wmd->texture, tex_co[i], &texres);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*get dist*/
|
||||||
|
if(wmd->flag & MOD_WAVE_X) {
|
||||||
|
if(wmd->flag & MOD_WAVE_Y){
|
||||||
|
dist = (float)sqrt(x*x + y*y);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dist = fabs(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(wmd->flag & MOD_WAVE_Y) {
|
||||||
|
dist = fabs(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
falloff_fac = (1.0-(dist / wmd->falloff));
|
||||||
|
CLAMP(falloff_fac,0,1);
|
||||||
|
|
||||||
|
if(wmd->flag & MOD_WAVE_X) {
|
||||||
|
if(wmd->flag & MOD_WAVE_Y) amplit = (float)sqrt(x*x + y*y);
|
||||||
|
else amplit = x;
|
||||||
|
}
|
||||||
|
else if(wmd->flag & MOD_WAVE_Y)
|
||||||
|
amplit= y;
|
||||||
|
|
||||||
|
/* this way it makes nice circles */
|
||||||
|
amplit -= (ctime - wmd->timeoffs) * wmd->speed;
|
||||||
|
|
||||||
|
if(wmd->flag & MOD_WAVE_CYCL) {
|
||||||
|
amplit = (float)fmod(amplit - wmd->width, 2.0 * wmd->width)
|
||||||
|
+ wmd->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GAUSSIAN */
|
||||||
|
if(amplit > -wmd->width && amplit < wmd->width) {
|
||||||
|
amplit = amplit * wmd->narrow;
|
||||||
|
amplit = (float)(1.0 / exp(amplit * amplit) - minfac);
|
||||||
|
|
||||||
|
/*apply texture*/
|
||||||
|
if(wmd->texture)
|
||||||
|
amplit = amplit * texres.tin;
|
||||||
|
|
||||||
|
/*apply weight*/
|
||||||
|
if(def_weight)
|
||||||
|
amplit = amplit * def_weight->weight;
|
||||||
|
|
||||||
|
/*apply falloff*/
|
||||||
|
if (wmd->falloff > 0)
|
||||||
|
amplit = amplit * falloff_fac;
|
||||||
|
|
||||||
|
if(mvert) {
|
||||||
|
/* move along normals */
|
||||||
|
if(wmd->flag & MOD_WAVE_NORM_X) {
|
||||||
|
co[0] += (lifefac * amplit) * mvert[i].no[0] / 32767.0f;
|
||||||
|
}
|
||||||
|
if(wmd->flag & MOD_WAVE_NORM_Y) {
|
||||||
|
co[1] += (lifefac * amplit) * mvert[i].no[1] / 32767.0f;
|
||||||
|
}
|
||||||
|
if(wmd->flag & MOD_WAVE_NORM_Z) {
|
||||||
|
co[2] += (lifefac * amplit) * mvert[i].no[2] / 32767.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* move along local z axis */
|
||||||
|
co[2] += lifefac * amplit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wmd->texture) MEM_freeN(tex_co);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVerts(
|
||||||
|
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||||
|
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= derivedData;
|
||||||
|
WaveModifierData *wmd = (WaveModifierData *)md;
|
||||||
|
|
||||||
|
if(wmd->flag & MOD_WAVE_NORM)
|
||||||
|
dm= get_cddm(md->scene, ob, NULL, dm, vertexCos);
|
||||||
|
else if(wmd->texture || wmd->defgrp_name[0])
|
||||||
|
dm= get_dm(md->scene, ob, NULL, dm, NULL, 0);
|
||||||
|
|
||||||
|
waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deformVertsEM(
|
||||||
|
ModifierData *md, Object *ob, EditMesh *editData,
|
||||||
|
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||||
|
{
|
||||||
|
DerivedMesh *dm= derivedData;
|
||||||
|
WaveModifierData *wmd = (WaveModifierData *)md;
|
||||||
|
|
||||||
|
if(wmd->flag & MOD_WAVE_NORM)
|
||||||
|
dm= get_cddm(md->scene, ob, editData, dm, vertexCos);
|
||||||
|
else if(wmd->texture || wmd->defgrp_name[0])
|
||||||
|
dm= get_dm(md->scene, ob, editData, dm, NULL, 0);
|
||||||
|
|
||||||
|
waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
|
||||||
|
|
||||||
|
if(dm != derivedData)
|
||||||
|
dm->release(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModifierTypeInfo modifierType_Wave = {
|
||||||
|
/* name */ "Wave",
|
||||||
|
/* structName */ "WaveModifierData",
|
||||||
|
/* structSize */ sizeof(WaveModifierData),
|
||||||
|
/* type */ eModifierTypeType_OnlyDeform,
|
||||||
|
/* flags */ eModifierTypeFlag_AcceptsCVs
|
||||||
|
| eModifierTypeFlag_SupportsEditmode,
|
||||||
|
/* copyData */ copyData,
|
||||||
|
/* deformVerts */ deformVerts,
|
||||||
|
/* deformVertsEM */ deformVertsEM,
|
||||||
|
/* deformMatricesEM */ 0,
|
||||||
|
/* applyModifier */ 0,
|
||||||
|
/* applyModifierEM */ 0,
|
||||||
|
/* initData */ initData,
|
||||||
|
/* requiredDataMask */ requiredDataMask,
|
||||||
|
/* freeData */ 0,
|
||||||
|
/* isDisabled */ 0,
|
||||||
|
/* updateDepgraph */ updateDepgraph,
|
||||||
|
/* dependsOnTime */ dependsOnTime,
|
||||||
|
/* foreachObjectLink */ foreachObjectLink,
|
||||||
|
/* foreachIDLink */ foreachIDLink,
|
||||||
|
};
|
||||||
@@ -359,7 +359,6 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||||||
SET(BLENDER_SORTED_LIBS
|
SET(BLENDER_SORTED_LIBS
|
||||||
bf_windowmanager
|
bf_windowmanager
|
||||||
bf_editors
|
bf_editors
|
||||||
bf_decimation
|
|
||||||
blender_BSP
|
blender_BSP
|
||||||
bf_ghost
|
bf_ghost
|
||||||
bf_string
|
bf_string
|
||||||
@@ -369,6 +368,7 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||||||
bf_gen_python
|
bf_gen_python
|
||||||
bf_ikplugin
|
bf_ikplugin
|
||||||
bf_blenkernel
|
bf_blenkernel
|
||||||
|
bf_modifiers
|
||||||
bf_nodes
|
bf_nodes
|
||||||
bf_gpu
|
bf_gpu
|
||||||
bf_blenloader
|
bf_blenloader
|
||||||
@@ -427,6 +427,7 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||||||
bf_dna
|
bf_dna
|
||||||
bf_blenfont
|
bf_blenfont
|
||||||
bf_audaspace
|
bf_audaspace
|
||||||
|
bf_decimation
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(WITH_CXX_GUARDEDALLOC)
|
IF(WITH_CXX_GUARDEDALLOC)
|
||||||
|
|||||||
Reference in New Issue
Block a user