1
1

Compare commits

...

52 Commits

Author SHA1 Message Date
2658a3c1b4 Merge branch 'master' into soc-2013-sketch_mesh
Conflicts:
	release/scripts/addons
	source/blender/blenloader/intern/readfile.c
	source/blender/blenloader/intern/writefile.c
	source/blender/editors/object/object_modifier.c
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/intern/MOD_laplaciandeform.c
2013-12-11 11:10:22 -05:00
4005cb1c6a Merge branch 'master' into soc-2013-sketch_mesh 2013-11-25 08:59:33 -05:00
65e409541c I adjusted some variables names.
The modifier sends a message on screen if the system not found a solution: (The Modifier not determines if a system is soluble, the numeric solver OpenNL Superlu notifies if solution was found.)
Fix bugs:
- Load file in a correct way.
- Delete vertex co (float array) when the bind flag is false.
2013-11-22 15:04:11 -05:00
6d96e75f6f Code Cleanup: minor changes to laplacian deform modifier interface 2013-11-22 09:35:19 +11:00
398ac1d472 Code Cleanup: style edits and avoid sqrt 2013-11-22 09:18:18 +11:00
198abc6b4b Code Cleanup: includes and warnings 2013-11-22 09:17:14 +11:00
d95a4903f1 Changed the names of some variables.
The modifier print on screnn an alert when the user change the vertices, edges, or vertex group.
2013-11-21 13:50:19 -05:00
70174fd1c2 Create of new Operator for bind Laplacian Deform Modifier
The Laplacian Deform Modifier bind the initial vertexes positions.
I Modified the LaplacianDeformModifierData struct to store bind state.
2013-11-20 20:25:53 -05:00
9c826cf9f5 Add eModifierTypeFlag_SupportsEditmode to support modifier in EditMode 2013-11-20 16:05:33 -05:00
a8a7b50421 Merge branch 'master' into soc-2013-sketch_mesh 2013-11-20 09:18:04 -05:00
494d2f9806 svn merge ^/trunk/blender 60972:61239 2013-11-12 20:30:26 +00:00
7d0c00ec90 Changes suggested by Campbell:
- Delete pointer to DeriveMesh
- Store face tessellation
2013-11-06 23:06:11 +00:00
90b189f3b9 The LaplacianDeform modifier only use DeriveMesh.
Fix bug: about only support mesh with faces
2013-11-05 23:15:46 +00:00
e1c25adb15 remove use of BLI_array 2013-11-05 12:11:25 +00:00
a8a88cadd2 minor changes, remove some NULL checks for allocating small arrays. 2013-11-05 12:04:46 +00:00
af23d6fb0d rename rna repetitions to iterations 2013-11-05 11:50:05 +00:00
4e45cc3b2c replace calloc for malloc in places, also minor style edits. 2013-11-05 11:46:08 +00:00
5efb67de09 code cleanup: style 2013-11-05 10:09:51 +00:00
454dea6ed5 branch now compiles on linux (minor fixes) 2013-11-03 16:02:33 +00:00
f854870d0b Fix a bug when the user modify the vertex positions in edit mode 2013-10-31 21:56:04 +00:00
fe4bf2dc1c The Laplacian deform eliminates the uses of BMesh .
The system now supports NGons
2013-10-30 22:03:59 +00:00
d57294f9c3 svn merge ^/trunk/blender 60786:60972 2013-10-28 22:22:31 +00:00
f49d5789e8 Style cleanup: Coding Style. 2013-10-28 21:22:41 +00:00
c23e365416 Style cleanup: Coding Style. 2013-10-23 20:12:15 +00:00
ebcf9192d4 Style cleanup: Coding Style. 2013-10-17 17:49:06 +00:00
7bfd0aae83 svn merge ^/trunk/blender 60616:60786 2013-10-15 17:55:57 +00:00
f833606792 The system can now iterates to improve the solution found.
The system at each iteration estimated in a better way the rotation of the differential coordinates
2013-10-15 17:17:27 +00:00
50bad88691 Do not solve the system again if a initial solution was not found 2013-10-10 15:19:41 +00:00
988bcb6ff9 Code was clean, some problems were fixed.
The system can store and retrieve the cache information from a file.
2013-10-10 02:04:27 +00:00
6b3a34d2c9 svn merge ^/trunk/blender 59138:60616 2013-10-08 19:08:21 +00:00
d57f58cfc6 I implement a simple method for capturing the silhouette based on an algorithm that works in the object space.
In the implemented method the user selects a region of interest. In this region the silhouette is detected, and the vertices in this silhouette will be the handlers. The vertices that are not in the region of interest are marked as static vertices.
2013-08-24 01:53:33 +00:00
24469d08df Now the deformation method does not require static vertices, only with the handles can solve the system. 2013-08-14 23:29:55 +00:00
54741c2311 svn merge ^/trunk/blender 58498:59138 2013-08-14 19:49:37 +00:00
0b09beb167 Frees a BMesh data, obtained from the function DM_to_bmesh. 2013-07-27 20:42:43 +00:00
22112779cb Implement the deformed Laplacian as a modifier.
The Laplacian Deform modifier, used two vertexGroups one for static and one for vertices's handlers.
By implementing the tool as Modifier allowed the use of other modifiers as Hook, so that the vertices's handlers can be controlled by various Hook objects.
2013-07-27 01:15:30 +00:00
c80af0190d svn merge ^/trunk/blender 58270:58498 2013-07-22 16:41:36 +00:00
c32f0ed4a2 The code is optimized by minimizing the linear system access. 2013-07-21 19:06:17 +00:00
e77def8edd Variables are initialized with the positions of the vertices so that the system does not take into account the trivial zero solution. 2013-07-21 16:46:00 +00:00
cebda88fe4 Add OpenNL include to Scons script. 2013-07-17 21:28:48 +00:00
b10685ba15 The system now factored matrix only one time, then only processes the solution.
The system can calculate the solution of automatic form after rotate, translate or scale the vertices handlers.
2013-07-17 21:24:26 +00:00
e1ef919164 I restricted some keyboard events.
I wrote a descriptive message of support in the area of the screen.
2013-07-17 01:11:32 +00:00
0a383de9e9 Test files were removed.
I remove the computation of implicit rotations because not improve the solution.
I eliminate the use of the library Eigen3 in my system because SuperLU library has better performance.
2013-07-16 23:32:23 +00:00
11e5988779 Testing deformation without compute implicit rotations.
Implicit rotations cause erroneous solutions.
2013-07-16 00:39:55 +00:00
c94626247a svn merge ^/trunk/blender 58040:58270 2013-07-15 15:06:14 +00:00
be1ff03f0d The code was organized and optimized.
The system has problems with the handling of events.
The deformation system is activated with the special menu key W "Laplacian Deform" in vertex editing mode.
The system works with keys Pkey, Hkey, Skey
You must mark the static vertices with Skey, then the handlers with hkey, and then you can move the handles and calculate the deformation with Pkey.
2013-07-14 21:54:15 +00:00
6bb5023ace Mesh Sketch based on Laplacian Deform implemented as EditMesh tool. 2013-07-12 02:37:55 +00:00
a936cb75b2 svn merge ^/trunk/blender 57829:58040 2013-07-06 20:50:49 +00:00
d940ab2747 Problem with merge 2013-07-06 19:37:12 +00:00
5441239955 svn merge ^/trunk/blender -r57381:57829 2013-06-27 18:20:47 +00:00
563535cbec implementation of the method to rotate the coordinate differentials 2013-06-27 17:30:53 +00:00
d20fa0ae3c Implementation of the system of equations for the deformation with preservation of detail.
Calculating the implied rotation for differential coordinates
2013-06-26 20:07:49 +00:00
1e8ad4d266 Create soc-2013-sketch_mesh for Sketch Mesh Editing project 2013-06-11 19:32:11 +00:00
11 changed files with 1014 additions and 4 deletions

View File

@@ -2034,6 +2034,7 @@ class VIEW3D_MT_edit_mesh_specials(Menu):
layout.operator("mesh.flip_normals")
layout.operator("mesh.vertices_smooth", text="Smooth")
layout.operator("mesh.vertices_smooth_laplacian", text="Laplacian Smooth")
layout.operator("mesh.vertices_laplacian_deform", text="Laplacian Deform")
layout.separator()

View File

@@ -32,6 +32,7 @@ set(INC
../../render/extern/include
../../windowmanager
../../../../intern/guardedalloc
../../../../intern/opennl/extern
)
set(INC_SYS
@@ -42,7 +43,7 @@ set(SRC
editface.c
editmesh_add.c
editmesh_bevel.c
editmesh_bisect.c
editmesh_deform_laplacian.c editmesh_bisect.c
editmesh_extrude.c
editmesh_inset.c
editmesh_knife.c

View File

@@ -34,6 +34,7 @@ defs = []
incs = [
'#/intern/guardedalloc',
'#/extern/glew/include',
'#/intern/opennl/extern',
'../include',
'../uvedit',
'../../blenfont',

View File

@@ -0,0 +1,986 @@
/*
* ***** 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.
*
* Contributor(s): Alexander Pinzon
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/mesh/editmesh_deform_laplacian.c
* \ingroup mesh
*
* Deform Laplacian.
*/
#include "WM_api.h"
#include "WM_types.h"
#include "DNA_object_types.h"
#include "UI_resources.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "mesh_intern.h" /* own include */
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_bvh.h"
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_array.h"
#include "BLI_string.h"
#include "ONL_opennl.h"
#include "BLF_translation.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h"
#include "ED_mesh.h"
struct BStaticAnchors {
int numStatics; /* Number of static anchors*/
int numVerts; /* Number of verts*/
int * list_index; /* Static vertex index list*/
bool *list_statics;
float (*co)[3]; /* Original vertex coordinates*/
float (*no)[3]; /* Original vertex normal*/
BMVert ** list_verts; /* Vertex order by index*/
};
typedef struct BStaticAnchors StaticAnchors;
struct BHandlerAnchors {
int numHandlers; /* Number of handler anchors*/
int * list_handlers; /* Static vertex index list*/
};
typedef struct BHandlerAnchors HandlerAnchors;
struct BLaplacianSystem {
float (*delta)[3]; /* Differential Coordinates*/
int *list_uverts; /* Unit vectors of projected edges onto the plane orthogonal to n*/
/* Pointers to data*/
int numVerts;
int numHandlers;
int numStatics;
BMesh *bm;
NLContext *context; /* System for solve general implicit rotations*/
};
typedef struct BLaplacianSystem LaplacianSystem;
enum {
LAP_STATE_INIT = 1,
LAP_STATE_HAS_STATIC,
LAP_STATE_HAS_HANDLER,
LAP_STATE_HAS_STATIC_AND_HANDLER,
LAP_STATE_HAS_L_COMPUTE,
LAP_STATE_UPDATE_REQUIRED
};
struct BSystemCustomData {
LaplacianSystem * sys;
StaticAnchors * sa;
HandlerAnchors * shs;
int stateSystem;
bool update_required;
Object *ob;
};
typedef struct BSystemCustomData SystemCustomData;
enum {
LAP_MODAL_CANCEL = 1,
LAP_MODAL_CONFIRM,
LAP_MODAL_PREVIEW,
LAP_MODAL_MARK_STATIC,
LAP_MODAL_MARK_HANDLER,
LAP_MODAL_TRANSFORM,
LAP_MODAL_NOTHING
};
static StaticAnchors * init_static_anchors(int numv, int nums);
static HandlerAnchors * init_handler_anchors(int numh);
static LaplacianSystem * init_laplacian_system(int numv, int nums, int numh);
static float cotan_weight(float *v1, float *v2, float *v3);
static int laplacian_deform_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *evt);
static int laplacian_deform_modal(bContext *C, wmOperator *op, const wmEvent *event);
static void laplacian_deform_cancel(bContext *C, wmOperator *op);
static void laplacian_deform_update_header(bContext *C);
static void compute_implict_rotations(SystemCustomData * data);
static void delete_void_pointer(void *data);
static void delete_static_anchors(StaticAnchors * sa);
static void delete_handler_anchors(HandlerAnchors * sh);
static void delete_laplacian_system(LaplacianSystem *sys);
static void init_laplacian_matrix( SystemCustomData * data);
static void laplacian_deform_mark_static(bContext *C, wmOperator *op);
static void laplacian_deform_mark_handlers(bContext *C, wmOperator *op);
static void laplacian_deform_preview(bContext *C, wmOperator *op);
static void rotate_differential_coordinates(SystemCustomData * data);
static void update_system_state(SystemCustomData * data, int state);
static void delete_void_pointer(void *data)
{
if (data) {
MEM_freeN(data);
}
}
static StaticAnchors * init_static_anchors(int numv, int nums)
{
StaticAnchors * sa;
sa = (StaticAnchors *)MEM_callocN(sizeof(StaticAnchors), "LapStaticAnchors");
sa->numVerts = numv;
sa->numStatics = nums;
sa->list_index = (int *)MEM_callocN(sizeof(int)*(sa->numStatics), "LapListStatics");
sa->list_statics = (bool *)MEM_callocN(sizeof(bool)*(sa->numVerts), "LapListBoolStatics");
sa->list_verts = (BMVert**)MEM_callocN(sizeof(BMVert*)*(sa->numVerts), "LapListverts");
sa->co = (float (*)[3])MEM_callocN(sizeof(float)*(sa->numVerts*3), "LapCoordinates");
sa->no = (float (*)[3])MEM_callocN(sizeof(float)*(sa->numVerts*3), "LapNormals");
memset(sa->no, 0.0, sizeof(float) * sa->numVerts * 3);
return sa;
}
static HandlerAnchors * init_handler_anchors(int numh)
{
HandlerAnchors * sh;
sh = (HandlerAnchors *)MEM_callocN(sizeof(HandlerAnchors), "LapHandlerAnchors");
sh->numHandlers = numh;
sh->list_handlers = (int *)MEM_callocN(sizeof(int)*(sh->numHandlers), "LapListHandlers");
return sh;
}
static LaplacianSystem * init_laplacian_system(int numv, int nums, int numh)
{
LaplacianSystem *sys;
int rows, cols;
sys = (LaplacianSystem *)MEM_callocN(sizeof(LaplacianSystem), "LapSystem");
if (!sys) {
return NULL;
}
sys->numVerts = numv;
sys->numStatics = nums;
sys->numHandlers = numh;
rows = (sys->numVerts + sys->numStatics + sys->numHandlers) * 3;
cols = sys->numVerts * 3;
sys->list_uverts = (int *)MEM_callocN(sizeof(BMVert *) * sys->numVerts, "LapUverts");
sys->delta = (float (*)[3])MEM_callocN(sizeof(float) * cols, "LapDelta");
return sys;
}
static void delete_static_anchors(StaticAnchors * sa)
{
if (!sa) return;
delete_void_pointer(sa->co);
delete_void_pointer(sa->list_index);
delete_void_pointer(sa->no);
delete_void_pointer(sa->list_verts);
delete_void_pointer(sa->list_statics);
delete_void_pointer(sa);
sa = NULL;
}
static void delete_handler_anchors(HandlerAnchors * sh)
{
if (!sh) return;
delete_void_pointer(sh->list_handlers);
delete_void_pointer(sh);
sh = NULL;
}
static void delete_laplacian_system(LaplacianSystem *sys)
{
if (!sys) return;
delete_void_pointer(sys->delta);
delete_void_pointer(sys->list_uverts);
sys->bm = NULL;
if (sys->context) nlDeleteContext(sys->context);
delete_void_pointer(sys);
sys = NULL;
}
void MESH_OT_vertices_laplacian_deform(wmOperatorType *ot)
{
ot->name = "Laplacian Deform Edit Mesh tool";
ot->description = "Laplacian Deform Mesh tool";
ot->idname = "MESH_OT_vertices_laplacian_deform";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
ot->invoke = laplacian_deform_invoke;
ot->modal = laplacian_deform_modal;
ot->cancel = laplacian_deform_cancel;
ot->poll = ED_operator_editmesh_view3d;
}
static void update_system_state(SystemCustomData * data, int state)
{
if (!data) return;
switch(data->stateSystem) {
case LAP_STATE_INIT:
if (state == LAP_STATE_HAS_STATIC || state == LAP_STATE_HAS_HANDLER) {
data->stateSystem = state;
}
break;
case LAP_STATE_HAS_STATIC:
if (state == LAP_STATE_HAS_HANDLER) {
data->stateSystem = LAP_STATE_HAS_STATIC_AND_HANDLER;
}
break;
case LAP_STATE_HAS_HANDLER:
if (state == LAP_STATE_HAS_STATIC) {
data->stateSystem = LAP_STATE_HAS_STATIC_AND_HANDLER;
}
break;
case LAP_STATE_HAS_STATIC_AND_HANDLER:
if (state == LAP_STATE_HAS_L_COMPUTE) {
data->stateSystem = LAP_STATE_HAS_L_COMPUTE;
}
break;
case LAP_STATE_HAS_L_COMPUTE:
if (state == LAP_STATE_HAS_STATIC || state == LAP_STATE_HAS_HANDLER) {
data->stateSystem = LAP_STATE_HAS_STATIC_AND_HANDLER;
}
break;
}
}
static int laplacian_deform_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SystemCustomData * sys;
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
view3d_operator_needs_opengl(C);
sys = op->customdata = MEM_callocN(sizeof(SystemCustomData), "LapSystemCustomData");
if (!sys) {
return OPERATOR_CANCELLED;
}
sys->sa = NULL;
sys->shs = NULL;
sys->sys = NULL;
sys->stateSystem = LAP_STATE_INIT;
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
WM_event_add_modal_handler(C, op);
laplacian_deform_update_header(C);
return OPERATOR_RUNNING_MODAL;
}
static void laplacian_deform_mark_static(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
SystemCustomData * data = op->customdata;
int vid, i, nums;
BMIter viter;
BMVert *v;
nums = BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, em->bm, BM_ELEM_SELECT, false);
if (data->sa) {
if (data->sa->numVerts != em->bm->totvert) {
delete_static_anchors(data->sa);
data->sa = init_static_anchors(em->bm->totvert, nums);
}
else {
delete_void_pointer( data->sa->list_index);
data->sa->numStatics = nums;
data->sa->list_index = (int *)MEM_callocN(sizeof(int)*(data->sa->numStatics), "LapListStatics");
data->sa->list_statics = (bool *)MEM_callocN(sizeof(bool)*(data->sa->numVerts), "LapListStatics");
}
}
else {
data->sa = init_static_anchors(em->bm->totvert, nums);
}
i=0;
BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
vid = BM_elem_index_get(v);
copy_v3_v3(data->sa->co[vid], v->co);
data->sa->list_verts[vid] = v;
data->sa->list_statics[vid] = false;
if (!BM_elem_flag_test_bool(v, BM_ELEM_SELECT)) {
data->sa->list_index[i] = vid;
i = i + 1;
data->sa->list_statics[vid] = true;
}
}
update_system_state(data, LAP_STATE_HAS_STATIC);
laplacian_deform_mark_handlers(C, op);
}
static void copy_m4_v16(float mout[4][4], double vin[16])
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
mout[i][j] = (float)vin[i * 4 + j];
}
}
}
static void laplacian_deform_mark_handlers(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
SystemCustomData * data = op->customdata;
BMIter viter, eiter, fiter;
BMVert *v;
BMEdge *e;
BMFace *f;
int vid, i, numh, nf, vid1, vid2;
bglMats mats;
float mview[4][4], iview[4][4];
float vp[3], ni[2];
view3d_operator_needs_opengl(C);
vp[0] = 0.0f; vp[1] = 0.0f; vp[2] = 0.0f;
bgl_get_mats(&mats);
copy_m4_v16(mview, mats.modelview);
invert_m4_m4(iview, mview);
mul_m4_v3(iview, vp);
invert_m4_m4(obedit->imat, obedit->obmat);
mul_m4_v3(obedit->imat, vp);
BM_ITER_MESH(v, &viter, em->bm, BM_VERTS_OF_MESH) {
BM_elem_flag_set(v, BM_ELEM_SELECT, false);
}
BM_ITER_MESH(f, &fiter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(f, BM_ELEM_SELECT, false);
}
BM_ITER_MESH(e, &eiter, em->bm, BM_EDGES_OF_MESH) {
BM_elem_flag_set(e, BM_ELEM_SELECT, false);
}
BM_ITER_MESH(e, &eiter, em->bm, BM_EDGES_OF_MESH) {
nf = 0;
vid1 = BM_elem_index_get(e->v1);
vid2 = BM_elem_index_get(e->v2);
if (data->sa->list_statics[vid1]==false && data->sa->list_statics[vid2]==false){
BM_ITER_ELEM(f, &fiter, e, BM_FACES_OF_EDGE) {
ni[nf] = dot_v3v3(f->no, vp);
nf = nf + 1;
}
if (nf == 2) {
if (ni[0]*ni[1] <=0) {
BM_elem_flag_set(e->v1, BM_ELEM_SELECT, true);
BM_elem_flag_set(e->v2, BM_ELEM_SELECT, true);
}
}
}
//else {
// BM_elem_flag_set(e->v1, BM_ELEM_SELECT, false);
// BM_elem_flag_set(e->v2, BM_ELEM_SELECT, false);
//}
}
numh = BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, em->bm, BM_ELEM_SELECT, true);
if (data->shs) {
delete_handler_anchors(data->shs);
}
data->shs = init_handler_anchors(numh);
i = 0;
BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
vid = BM_elem_index_get(v);
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
data->shs->list_handlers[i] = vid;
i = i + 1;
}
}
update_system_state(data, LAP_STATE_HAS_HANDLER);
}
static float cotan_weight(float *v1, float *v2, float *v3)
{
float a[3], b[3], c[3], clen;
sub_v3_v3v3(a, v2, v1);
sub_v3_v3v3(b, v3, v1);
cross_v3_v3v3(c, a, b);
clen = len_v3(c);
if (clen < FLT_EPSILON)
return 0.0f;
return dot_v3v3(a, b) / clen;
}
static void init_laplacian_matrix( SystemCustomData * data)
{
float v1[3], v2[3], v3[3], v4[3], no[3];
float w2, w3, w4;
int i, j, vid, vidf[4];
bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4, idv[4];
BMFace *f;
BMIter fiter;
BMIter vi;
BMVert *vn;
LaplacianSystem * sys = data->sys;
StaticAnchors * sa = data->sa;
BM_ITER_MESH (f, &fiter, sys->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) {
vid = BM_elem_index_get(vn);
vidf[i] = vid;
}
has_4_vert = (i == 4) ? 1 : 0;
idv1 = vidf[0];
idv2 = vidf[1];
idv3 = vidf[2];
idv4 = has_4_vert ? vidf[3] : 0;
if (has_4_vert) {
normal_quad_v3(no, sa->co[idv1], sa->co[idv2], sa->co[idv3], sa->co[idv4]);
add_v3_v3(sa->no[idv4], no);
}
else {
normal_tri_v3(no, sa->co[idv1], sa->co[idv2], sa->co[idv3]);
}
add_v3_v3(sa->no[idv1], no);
add_v3_v3(sa->no[idv2], no);
add_v3_v3(sa->no[idv3], no);
idv[0] = idv1;
idv[1] = idv2;
idv[2] = idv3;
idv[3] = idv4;
for (j = 0; j < i; j++) {
idv1 = idv[j];
idv2 = idv[(j + 1) % i];
idv3 = idv[(j + 2) % i];
idv4 = has_4_vert ? idv[(j + 3) % i] : 0;
copy_v3_v3( v1, sa->co[idv1]);
copy_v3_v3( v2, sa->co[idv2]);
copy_v3_v3( v3, sa->co[idv3]);
if (has_4_vert) copy_v3_v3(v4, sa->co[idv4]);
if (has_4_vert) {
w2 = (cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2)) /2.0f ;
w3 = (cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3)) /2.0f ;
w4 = (cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1)) /2.0f;
sys->delta[idv1][0] -= v4[0] * w4;
sys->delta[idv1][1] -= v4[1] * w4;
sys->delta[idv1][2] -= v4[2] * w4;
nlRightHandSideAdd(0, idv1, -v4[0] * w4);
nlRightHandSideAdd(1, idv1, -v4[1] * w4);
nlRightHandSideAdd(2, idv1, -v4[2] * w4);
nlMatrixAdd(idv1, idv4, -w4 );
}
else {
w2 = cotan_weight(v3, v1, v2);
w3 = cotan_weight(v2, v3, v1);
w4 = 0.0f;
}
sys->delta[idv1][0] += v1[0] * (w2 + w3 + w4);
sys->delta[idv1][1] += v1[1] * (w2 + w3 + w4);
sys->delta[idv1][2] += v1[2] * (w2 + w3 + w4);
sys->delta[idv1][0] -= v2[0] * w2;
sys->delta[idv1][1] -= v2[1] * w2;
sys->delta[idv1][2] -= v2[2] * w2;
sys->delta[idv1][0] -= v3[0] * w3;
sys->delta[idv1][1] -= v3[1] * w3;
sys->delta[idv1][2] -= v3[2] * w3;
nlMatrixAdd(idv1, idv2, -w2);
nlMatrixAdd(idv1, idv3, -w3);
nlMatrixAdd(idv1, idv1, w2 + w3 + w4);
}
}
}
static void compute_implict_rotations(SystemCustomData * data)
{
BMEdge *e;
BMIter eiter;
BMIter viter;
BMVert *v;
int vid, * vidn = NULL;
float minj, mjt, qj[3], vj[3];
int i, j, ln;
LaplacianSystem * sys = data->sys;
StaticAnchors * sa = data->sa;
BLI_array_declare(vidn);
BM_ITER_MESH (v, &viter, sys->bm, BM_VERTS_OF_MESH) {
i = BM_elem_index_get(v);
normalize_v3( sa->no[i]);
BM_ITER_ELEM(e, &eiter, v, BM_EDGES_OF_VERT) {
vid = BM_elem_index_get(e->v1);
if (vid == i) {
vid = BM_elem_index_get(e->v2);
BLI_array_append(vidn, vid);
}
else {
BLI_array_append(vidn, vid);
}
}
BLI_array_append(vidn, i);
ln = BLI_array_count(vidn);
minj = 1000000.0f;
for (j = 0; j < (ln-1); j++) {
vid = vidn[j];
copy_v3_v3(qj, sa->co[vid]);// vn[j]->co;
sub_v3_v3v3(vj, qj, sa->co[i]); //sub_v3_v3v3(vj, qj, v->co);
normalize_v3(vj);
mjt = fabs(dot_v3v3(vj, sa->no[i])); //mjt = fabs(dot_v3v3(vj, v->no));
if (mjt < minj) {
minj = mjt;
sys->list_uverts[i] = vidn[j];
}
}
BLI_array_free(vidn);
BLI_array_empty(vidn);
vidn = NULL;
}
}
static void rotate_differential_coordinates(SystemCustomData * data)
{
BMFace *f;
BMVert *v, *v2;
BMIter fiter;
BMIter viter, viter2;
float alpha, beta, gamma,
pj[3], ni[3], di[3],
uij[3], dun[3], e2[3], pi[3], fni[3], vn[4][3];
int i, j, vin[4], lvin, num_fni, k;
LaplacianSystem * sys = data->sys;
StaticAnchors * sa = data->sa;
BM_ITER_MESH (v, &viter, sys->bm, BM_VERTS_OF_MESH) {
i = BM_elem_index_get(v);
copy_v3_v3(pi, sa->co[i]); //copy_v3_v3(pi, v->co);
copy_v3_v3(ni, sa->no[i]); //copy_v3_v3(ni, v->no);
k = sys->list_uverts[i];
copy_v3_v3(pj, sa->co[k]); //copy_v3_v3(pj, sys->uverts[i]->co);
sub_v3_v3v3(uij, pj, pi);
mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
sub_v3_v3(uij, dun);
normalize_v3(uij);
cross_v3_v3v3(e2, ni, uij);
copy_v3_v3(di, sys->delta[i]);
alpha = dot_v3v3(ni, di);
beta = dot_v3v3(uij, di);
gamma = dot_v3v3(e2, di);
pi[0] = nlGetVariable(0, i);
pi[1] = nlGetVariable(1, i);
pi[2] = nlGetVariable(2, i);
ni[0] = 0.0f; ni[1] = 0.0f; ni[2] = 0.0f;
num_fni = 0;
BM_ITER_ELEM_INDEX(f, &fiter, v, BM_FACES_OF_VERT, num_fni) {
BM_ITER_ELEM_INDEX(v2, &viter2, f, BM_VERTS_OF_FACE, j) {
vin[j] = BM_elem_index_get(v2);
}
lvin = j;
for (j=0; j<lvin; j++ ) {
vn[j][0] = nlGetVariable(0, vin[j]);
vn[j][1] = nlGetVariable(1, vin[j]);
vn[j][2] = nlGetVariable(2, vin[j]);
if (vin[j] == sys->list_uverts[i]) {
copy_v3_v3(pj, vn[j]);
}
}
if (lvin == 3) {
normal_tri_v3(fni, vn[0], vn[1], vn[2]);
}
else if(lvin == 4) {
normal_quad_v3(fni, vn[0], vn[1], vn[2], vn[3]);
}
add_v3_v3(ni, fni);
}
normalize_v3(ni);
sub_v3_v3v3(uij, pj, pi);
mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
sub_v3_v3(uij, dun);
normalize_v3(uij);
cross_v3_v3v3(e2, ni, uij);
fni[0] = alpha*ni[0] + beta*uij[0] + gamma*e2[0];
fni[1] = alpha*ni[1] + beta*uij[1] + gamma*e2[1];
fni[2] = alpha*ni[2] + beta*uij[2] + gamma*e2[2];
if (len_v3(fni) > FLT_EPSILON) {
nlRightHandSideSet(0, i, fni[0]);
nlRightHandSideSet(1, i, fni[1]);
nlRightHandSideSet(2, i, fni[2]);
}
else {
nlRightHandSideSet(0, i, sys->delta[i][0]);
nlRightHandSideSet(1, i, sys->delta[i][1]);
nlRightHandSideSet(2, i, sys->delta[i][2]);
}
}
}
static int laplacian_deform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SystemCustomData * data = op->customdata;
if (data) if (data->update_required) {
data->update_required = false;
printf("\nLAP_MODAL_PREVIEW\n");
laplacian_deform_preview(C, op);
laplacian_deform_update_header(C);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_RUNNING_MODAL;
}
if(event->type == EVT_MODAL_MAP) {
switch (event->val) {
case LAP_MODAL_CANCEL:
printf("\nLAP_MODAL_CANCEL\n");
ED_area_headerprint(CTX_wm_area(C), NULL);
laplacian_deform_cancel(C, op);
return OPERATOR_CANCELLED;
case LAP_MODAL_MARK_HANDLER:
printf("\nLAP_MODAL_MARK_HANDLER\n");
laplacian_deform_mark_handlers(C, op);
laplacian_deform_update_header(C);
break;
case LAP_MODAL_MARK_STATIC:
printf("\nLAP_MODAL_MARK_STATIC\n");
laplacian_deform_mark_static(C, op);
laplacian_deform_update_header(C);
break;
case LAP_MODAL_PREVIEW:
printf("\nLAP_MODAL_PREVIEW\n");
laplacian_deform_preview(C, op);
laplacian_deform_update_header(C);
ED_region_tag_redraw(CTX_wm_region(C));
break;
case LAP_MODAL_TRANSFORM:
printf("\nLAP_MODAL_TRANSFORM\n");
if (data) {
data->update_required = true;
}
return OPERATOR_PASS_THROUGH;
break;
case LAP_MODAL_NOTHING:
printf("\nLAP_MODAL_NOTHING\n");
return OPERATOR_PASS_THROUGH;
break;
/*default:
return OPERATOR_PASS_THROUGH;
break;*/
}
}
else {
if (event->type >= LEFTMOUSE && event->type <= WHEELOUTMOUSE) {
return OPERATOR_PASS_THROUGH;
}
}
return OPERATOR_RUNNING_MODAL;
}
static void laplacian_deform_cancel(bContext *UNUSED(C), wmOperator *op)
{
SystemCustomData * data;
data = op->customdata;
if (data) {
delete_laplacian_system(data->sys);
delete_static_anchors(data->sa);
delete_handler_anchors(data->shs);
data->ob = NULL;
delete_void_pointer(data);
}
}
wmKeyMap * laplacian_deform_modal_keymap(wmKeyConfig *keyconf)
{
static EnumPropertyItem modal_items[] = {
{LAP_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
{LAP_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
{LAP_MODAL_PREVIEW, "PREVIEW", 0, "Preview", ""},
{LAP_MODAL_MARK_STATIC, "MARK_STATIC", 0, "Mark Vertex as Static", ""},
{LAP_MODAL_MARK_HANDLER, "MARK_HANDLER", 0, "Mark Vertex as Handler", ""},
{LAP_MODAL_TRANSFORM, "TRANSFROM", 0, "Transform Verts", ""},
{0, NULL, 0, NULL, NULL}
};
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Laplacian Deform Modal Map");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items)
return NULL;
keymap = WM_modalkeymap_add(keyconf, "Laplacian Deform Modal Map", modal_items);
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, LAP_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, SPACEKEY, KM_PRESS, KM_ANY, 0, LAP_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, QKEY, KM_PRESS, 0, 0, LAP_MODAL_CANCEL);
//WM_modalkeymap_add_item(keymap, JKEY, KM_PRESS, 0, 0, LAP_MODAL_MARK_HANDLER);
WM_modalkeymap_add_item(keymap, HKEY, KM_PRESS, 0, 0, LAP_MODAL_MARK_STATIC);
WM_modalkeymap_add_item(keymap, PKEY, KM_PRESS, 0, 0, LAP_MODAL_PREVIEW);
//WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, LAP_MODAL_TRANSFORM);
//WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, LAP_MODAL_TRANSFORM);
//WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, LAP_MODAL_TRANSFORM);
WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, TKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, NKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, BKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, CKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD0, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD1, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD2, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD3, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD4, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD5, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD6, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD7, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD8, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PAD9, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, LAP_MODAL_NOTHING);
WM_modalkeymap_assign(keymap, "MESH_OT_vertices_laplacian_deform");
return keymap;
}
static void laplacian_deform_update_header(bContext *C)
{
#define HEADER_LENGTH 256
char header[HEADER_LENGTH];
BLI_snprintf(header, HEADER_LENGTH, IFACE_("First Mark Static Anchors J, Second Mark Handler Anchors H, "
"Third Transform Handler Anchors, Fourth Compute solution P, Esc or Q: cancel, "));
ED_area_headerprint(CTX_wm_area(C), header);
}
static void laplacian_deform_preview(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
SystemCustomData * data = op->customdata;
LaplacianSystem * sys;
StaticAnchors * sa;
HandlerAnchors * shs;
struct BMesh *bm = em->bm;
int vid, i, n, ns, nh;
BMIter viter;
BMVert *v;
if (data->stateSystem < LAP_STATE_HAS_STATIC_AND_HANDLER) return;
if (data->stateSystem == LAP_STATE_HAS_STATIC_AND_HANDLER ) {
if (data->sys) {
delete_laplacian_system(data->sys);
}
data->sys = init_laplacian_system(data->sa->numVerts, data->sa->numStatics, data->shs->numHandlers);
sys = data->sys;
sa = data->sa;
shs = data->shs;
sys->bm = bm;
n = sys->numVerts;
ns = sa->numStatics;
nh = shs->numHandlers;
nlNewContext();
sys->context = nlGetCurrent();
nlSolverParameteri(NL_NB_VARIABLES, n);
nlSolverParameteri(NL_SYMMETRIC, NL_FALSE);
nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
nlSolverParameteri(NL_NB_ROWS, n + nh + ns);
nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3);
nlBegin(NL_SYSTEM);
for (i=0; i<n; i++) {
nlSetVariable(0, i, sa->co[i][0]);
nlSetVariable(1, i, sa->co[i][1]);
nlSetVariable(2, i, sa->co[i][2]);
}
for (i=0; i<nh; i++) {
vid = shs->list_handlers[i];
nlSetVariable(0, vid, sa->list_verts[vid]->co[0]);
nlSetVariable(1, vid, sa->list_verts[vid]->co[1]);
nlSetVariable(2, vid, sa->list_verts[vid]->co[2]);
}
for (i=0; i<ns; i++) {
nlLockVariable(sa->list_index[i]);
}
nlBegin(NL_MATRIX);
init_laplacian_matrix(data);
compute_implict_rotations(data);
for (i=0; i<n; i++) {
nlRightHandSideSet(0, i, sys->delta[i][0]);
nlRightHandSideSet(1, i, sys->delta[i][1]);
nlRightHandSideSet(2, i, sys->delta[i][2]);
}
for (i=0; i<ns; i++) {
vid = sa->list_index[i];
nlRightHandSideSet(0, n + i , sa->co[vid][0]);
nlRightHandSideSet(1, n + i , sa->co[vid][1]);
nlRightHandSideSet(2, n + i , sa->co[vid][2]);
nlMatrixAdd(n + i, vid, 1.0f);
}
for (i=0; i<nh; i++)
{
vid = shs->list_handlers[i];
nlRightHandSideSet(0, n + ns + i , sa->list_verts[vid]->co[0]);
nlRightHandSideSet(1, n + ns + i , sa->list_verts[vid]->co[1]);
nlRightHandSideSet(2, n + ns + i , sa->list_verts[vid]->co[2]);
nlMatrixAdd(n + ns + i , vid , 1.0f);
}
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_TRUE) ) {
nlBegin(NL_SYSTEM);
nlBegin(NL_MATRIX);
rotate_differential_coordinates(data);
for (i=0; i<ns; i++) {
vid = sa->list_index[i];
nlRightHandSideSet(0, n + i , sa->co[vid][0]);
nlRightHandSideSet(1, n + i , sa->co[vid][1]);
nlRightHandSideSet(2, n + i , sa->co[vid][2]);
}
for (i=0; i<nh; i++)
{
vid = shs->list_handlers[i];
nlRightHandSideSet(0, n + ns + i , sa->list_verts[vid]->co[0]);
nlRightHandSideSet(1, n + ns + i , sa->list_verts[vid]->co[1]);
nlRightHandSideSet(2, n + ns + i , sa->list_verts[vid]->co[2]);
}
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_FALSE) ) {
BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
vid = BM_elem_index_get(v);
v->co[0] = nlGetVariable(0, vid);
v->co[1] = nlGetVariable(1, vid);
v->co[2] = nlGetVariable(2, vid);
}
}
printf("\nSystem solved");
}
else{
printf("\nNo solution found");
}
update_system_state(data, LAP_STATE_HAS_L_COMPUTE);
} else if (data->stateSystem == LAP_STATE_HAS_L_COMPUTE ) {
sys = data->sys;
sa = data->sa;
shs = data->shs;
sys->bm = bm;
n = sys->numVerts;
ns = sa->numStatics;
nh = shs->numHandlers;
nlBegin(NL_SYSTEM);
nlBegin(NL_MATRIX);
for (i=0; i<n; i++) {
nlRightHandSideSet(0, i , sys->delta[i][0]);
nlRightHandSideSet(1, i , sys->delta[i][1]);
nlRightHandSideSet(2, i , sys->delta[i][2]);
}
for (i=0; i<ns; i++) {
vid = sa->list_index[i];
nlRightHandSideSet(0, n + i , sa->co[vid][0]);
nlRightHandSideSet(1, n + i , sa->co[vid][1]);
nlRightHandSideSet(2, n + i , sa->co[vid][2]);
nlMatrixAdd(n + i, vid, 1.0f);
}
for (i=0; i<nh; i++)
{
vid = shs->list_handlers[i];
nlRightHandSideSet(0, n + ns + i , sa->list_verts[vid]->co[0]);
nlRightHandSideSet(1, n + ns + i , sa->list_verts[vid]->co[1]);
nlRightHandSideSet(2, n + ns + i , sa->list_verts[vid]->co[2]);
nlMatrixAdd(n + ns + i , vid , 1.0f);
}
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_FALSE) ) {
nlBegin(NL_SYSTEM);
nlBegin(NL_MATRIX);
rotate_differential_coordinates(data);
for (i=0; i<ns; i++) {
vid = sa->list_index[i];
nlRightHandSideSet(0, n + i , sa->co[vid][0]);
nlRightHandSideSet(1, n + i , sa->co[vid][1]);
nlRightHandSideSet(2, n + i , sa->co[vid][2]);
}
for (i=0; i<nh; i++)
{
vid = shs->list_handlers[i];
nlRightHandSideSet(0, n + ns + i , sa->list_verts[vid]->co[0]);
nlRightHandSideSet(1, n + ns + i , sa->list_verts[vid]->co[1]);
nlRightHandSideSet(2, n + ns + i , sa->list_verts[vid]->co[2]);
}
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_FALSE) ) {
BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
vid = BM_elem_index_get(v);
v->co[0] = nlGetVariable(0, vid);
v->co[1] = nlGetVariable(1, vid);
v->co[2] = nlGetVariable(2, vid);
}
}
printf("\nSystem solved 2");
}
else{
printf("\nNo solution found 2");
}
update_system_state(data, LAP_STATE_HAS_L_COMPUTE);
}
}

View File

@@ -121,6 +121,9 @@ void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys,
struct wmKeyMap *knifetool_modal_keymap(struct wmKeyConfig *keyconf);
/* *** editmesh_deform_laplacian.c *** */
void MESH_OT_vertices_laplacian_deform(struct wmOperatorType *ot);
struct wmKeyMap *laplacian_deform_modal_keymap(struct wmKeyConfig *keyconf);
/* *** editmesh_loopcut.c *** */
void MESH_OT_loopcut(struct wmOperatorType *ot);

View File

@@ -138,6 +138,7 @@ void ED_operatortypes_mesh(void)
#endif
WM_operatortype_append(MESH_OT_vertices_smooth);
WM_operatortype_append(MESH_OT_vertices_smooth_laplacian);
WM_operatortype_append(MESH_OT_vertices_laplacian_deform);
WM_operatortype_append(MESH_OT_noise);
WM_operatortype_append(MESH_OT_flip_normals);
WM_operatortype_append(MESH_OT_rip);
@@ -429,5 +430,6 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
ED_keymap_proportional_editmode(keyconf, keymap, true);
knifetool_modal_keymap(keyconf);
laplacian_deform_modal_keymap(keyconf);
}

View File

@@ -1305,6 +1305,21 @@ enum {
MOD_MESHCACHE_PLAY_EVAL = 1,
};
typedef struct LaplacianDeformModifierData {
ModifierData modifier;
char anchor_grp_name[64]; /* MAX_VGROUP_NAME */
int total_verts, repeat;
float *vertexco;
void *cacheSystem;
short flag, pad[3];
} LaplacianDeformModifierData;
/* Smooth modifier flags */
enum {
MOD_LAPLACIANDEFORM_BIND = 1,
};
typedef struct LaplacianDeformModifierData {
ModifierData modifier;

View File

@@ -298,6 +298,7 @@ extern StructRNA RNA_LampSkySettings;
extern StructRNA RNA_LampTextureSlot;
extern StructRNA RNA_LaplacianDeformModifier;
extern StructRNA RNA_LaplacianSmoothModifier;
extern StructRNA RNA_LaplacianDeformModifier;
extern StructRNA RNA_Lattice;
extern StructRNA RNA_LatticeModifier;
extern StructRNA RNA_LatticePoint;