Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editdeform.c')
-rw-r--r--source/blender/src/editdeform.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c
new file mode 100644
index 00000000000..7bce1aaa695
--- /dev/null
+++ b/source/blender/src/editdeform.c
@@ -0,0 +1,345 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Creator-specific support for vertex deformation groups
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_global.h"
+#include "BKE_deform.h"
+#include "BKE_mesh.h"
+
+#include "BIF_editdeform.h"
+#include "BIF_toolbox.h"
+
+void sel_verts_defgroup (int select)
+{
+ EditVert *eve;
+ Object *ob;
+ int i;
+
+ ob=G.obedit;
+
+ if (!ob)
+ return;
+
+ switch (ob->type){
+ case OB_MESH:
+ for (eve=G.edve.first; eve; eve=eve->next){
+ if (eve->totweight){
+ for (i=0; i<eve->totweight; i++){
+ if (eve->dw[i].def_nr == (ob->actdef-1)){
+ if (select) eve->f |= 1;
+ else eve->f &= ~1;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+}
+
+MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
+/* Ensures that mv has a deform weight entry for
+the specified defweight group */
+{
+ int i;
+ MDeformWeight *newdw;
+
+ if (!dv)
+ return NULL;
+
+ for (i=0; i<dv->totweight; i++){
+ if (dv->dw[i].def_nr == defgroup)
+ return dv->dw+i;
+ }
+
+ newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
+ if (dv->dw){
+ memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+ MEM_freeN (dv->dw);
+ }
+ dv->dw=newdw;
+
+ dv->dw[dv->totweight].weight=0;
+ dv->dw[dv->totweight].def_nr=defgroup;
+ /* Group index */
+
+ dv->totweight++;
+
+ return dv->dw+(dv->totweight-1);
+}
+
+void add_defgroup (Object *ob)
+{
+ bDeformGroup *defgroup;
+
+ if (!ob)
+ return;
+
+ defgroup = MEM_callocN (sizeof(bDeformGroup), "deformGroup");
+ strcpy (defgroup->name, "Group");
+
+ BLI_addtail(&ob->defbase, defgroup);
+ unique_vertexgroup_name(defgroup, ob);
+
+ ob->actdef = BLI_countlist(&ob->defbase);
+}
+
+void del_defgroup (Object *ob)
+{
+ bDeformGroup *defgroup;
+ EditVert *eve;
+ int i;
+
+
+ if (!ob)
+ return;
+
+ if (!ob->actdef)
+ return;
+
+ defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
+ if (!defgroup)
+ return;
+
+ /* Make sure that no verts are using this group */
+ remove_verts_defgroup(1);
+
+ /* Make sure that any verts with higher indices are adjusted accordingly */
+ for (eve=G.edve.first; eve; eve=eve->next){
+ for (i=0; i<eve->totweight; i++){
+ if (eve->dw[i].def_nr > (ob->actdef-1))
+ eve->dw[i].def_nr--;
+ }
+ }
+
+ /* Update the active material index if necessary */
+ if (ob->actdef==BLI_countlist(&ob->defbase))
+ ob->actdef--;
+
+ /* Remove the group */
+ BLI_freelinkN (&ob->defbase, defgroup);
+}
+
+void assign_verts_defgroup (void)
+/* Only available in editmode */
+{
+ Object *ob;
+ EditVert *eve;
+ bDeformGroup *dg, *eg;
+ extern float editbutvweight; /* buttons.c */
+ int i, done;
+ MDeformWeight *newdw;
+
+ ob=G.obedit;
+
+ if (!ob)
+ return;
+
+ dg=BLI_findlink(&ob->defbase, ob->actdef-1);
+ if (!dg){
+ error ("No vertex group active");
+ return;
+ }
+
+ switch (ob->type){
+ case OB_MESH:
+ /* Go through the list of editverts and assign them */
+ for (eve=G.edve.first; eve; eve=eve->next){
+ if (eve->f & 1){
+ done=0;
+ /* See if this vert already has a reference to this group */
+ /* If so: Change its weight */
+ done=0;
+ for (i=0; i<eve->totweight; i++){
+ eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr);
+ /* Find the actual group */
+ if (eg==dg){
+ eve->dw[i].weight=editbutvweight;
+ done=1;
+ break;
+ }
+ }
+ /* If not: Add the group and set its weight */
+ if (!done){
+ newdw = MEM_callocN (sizeof(MDeformWeight)*(eve->totweight+1), "deformWeight");
+ if (eve->dw){
+ memcpy (newdw, eve->dw, sizeof(MDeformWeight)*eve->totweight);
+ MEM_freeN (eve->dw);
+ }
+ eve->dw=newdw;
+
+ eve->dw[eve->totweight].weight=editbutvweight;
+ eve->dw[eve->totweight].def_nr=ob->actdef-1;
+
+ eve->totweight++;
+
+ }
+ }
+ }
+ break;
+ default:
+ printf ("Assigning deformation groups to unknown object type: Warn <reevan@blender.nl>\n");
+ break;
+ }
+
+}
+
+void remove_verts_defgroup (int allverts)
+/* Only available in editmode */
+{
+ Object *ob;
+ EditVert *eve;
+ MDeformWeight *newdw;
+ bDeformGroup *dg, *eg;
+ int i;
+
+ ob=G.obedit;
+
+ if (!ob)
+ return;
+
+ dg=BLI_findlink(&ob->defbase, ob->actdef-1);
+ if (!dg){
+ error ("No vertex group active");
+ return;
+ }
+
+ switch (ob->type){
+ case OB_MESH:
+ for (eve=G.edve.first; eve; eve=eve->next){
+ if (eve->dw && ((eve->f & 1) || allverts)){
+ for (i=0; i<eve->totweight; i++){
+ /* Find group */
+ eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr);
+ if (eg == dg){
+ eve->totweight--;
+ if (eve->totweight){
+ newdw = MEM_mallocN (sizeof(MDeformWeight)*(eve->totweight), "deformWeight");
+
+ if (eve->dw){
+ memcpy (newdw, eve->dw, sizeof(MDeformWeight)*i);
+ memcpy (newdw+i, eve->dw+i+1, sizeof(MDeformWeight)*(eve->totweight-i));
+ MEM_freeN (eve->dw);
+ }
+ eve->dw=newdw;
+ }
+ else{
+ MEM_freeN (eve->dw);
+ eve->dw=NULL;
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ printf ("Removing deformation groups from unknown object type: Warn <reevan@blender.nl>\n");
+ break;
+ }
+}
+
+void verify_defgroups (Object *ob)
+{
+ /* Ensure the defbase & the dverts match */
+ switch (ob->type){
+ case OB_MESH:
+ if (!ob->defbase.first){
+ if (((Mesh*)ob->data)->dvert){
+ free_dverts(((Mesh*)ob->data)->dvert, ((Mesh*)ob->data)->totvert);
+ ((Mesh*)ob->data)->dvert=NULL;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void unique_vertexgroup_name (bDeformGroup *dg, Object *ob)
+{
+ char tempname[64];
+ int number;
+ char *dot;
+ int exists = 0;
+ bDeformGroup *curdef;
+
+ if (!ob)
+ return;
+ /* See if we even need to do this */
+ for (curdef = ob->defbase.first; curdef; curdef=curdef->next){
+ if (dg!=curdef){
+ if (!strcmp(curdef->name, dg->name)){
+ exists = 1;
+ break;
+ }
+ }
+ }
+
+ if (!exists)
+ return;
+
+ /* Strip off the suffix */
+ dot=strchr(dg->name, '.');
+ if (dot)
+ *dot=0;
+
+ for (number = 1; number <=999; number++){
+ sprintf (tempname, "%s.%03d", dg->name, number);
+
+ exists = 0;
+ for (curdef=ob->defbase.first; curdef; curdef=curdef->next){
+ if (dg!=curdef){
+ if (!strcmp (curdef->name, tempname)){
+ exists = 1;
+ break;
+ }
+ }
+ }
+ if (!exists){
+ strcpy (dg->name, tempname);
+ return;
+ }
+ }
+}