Merging etch-a-ton branch in trunk.

Slightly out of date documentation in wiki, I'll be updating that tomorrow.

http://wiki.blender.org/index.php/User:Theeth/etch-a-ton
This commit is contained in:
Martin Poirier 2009-03-16 02:55:42 +00:00
commit 7d2703c805
31 changed files with 6045 additions and 1410 deletions

View File

@ -521,6 +521,7 @@ void unlink_object(Object *ob)
while(sce) {
if(sce->id.lib==NULL) {
if(sce->camera==ob) sce->camera= NULL;
if(sce->toolsettings->skgen_template==ob) sce->toolsettings->skgen_template = NULL;
}
sce= sce->id.next;
}

View File

@ -391,8 +391,10 @@ void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]);
int LineIntersectLineStrict(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda);
int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int RayIntersectsTriangleThreshold(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold);
int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
int AxialLineIntersectsTriangle(int axis, float co1[3], float co2[3], float v0[3], float v1[3], float v2[3], float *lambda);
int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]);

View File

@ -60,6 +60,39 @@ typedef struct BArc {
int symmetry_flag;
} BArc;
struct BArcIterator;
void* IT_head(void* iter);
void* IT_tail(void* iter);
void* IT_peek(void* iter, int n);
void* IT_next(void* iter);
void* IT_nextN(void* iter, int n);
void* IT_previous(void* iter);
int IT_stopped(void* iter);
typedef void* (*HeadFct)(void* iter);
typedef void* (*TailFct)(void* iter);
typedef void* (*PeekFct)(void* iter, int n);
typedef void* (*NextFct)(void* iter);
typedef void* (*NextNFct)(void* iter, int n);
typedef void* (*PreviousFct)(void* iter);
typedef int (*StoppedFct)(void* iter);
typedef struct BArcIterator {
HeadFct head;
TailFct tail;
PeekFct peek;
NextFct next;
NextNFct nextN;
PreviousFct previous;
StoppedFct stopped;
float *p, *no;
int length;
int index;
} BArcIterator;
/* Helper structure for radial symmetry */
typedef struct RadialArc
{

View File

@ -3896,6 +3896,57 @@ int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], flo
return 1;
}
int RayIntersectsTriangleThreshold(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold)
{
float p[3], s[3], e1[3], e2[3], q[3];
float a, f, u, v;
float du = 0, dv = 0;
VecSubf(e1, v1, v0);
VecSubf(e2, v2, v0);
Crossf(p, d, e2);
a = Inpf(e1, p);
if ((a > -0.000001) && (a < 0.000001)) return 0;
f = 1.0f/a;
VecSubf(s, p1, v0);
Crossf(q, s, e1);
*lambda = f * Inpf(e2, q);
if ((*lambda < 0.0)) return 0;
u = f * Inpf(s, p);
v = f * Inpf(d, q);
if (u < 0) du = u;
if (u > 1) du = u - 1;
if (v < 0) dv = v;
if (v > 1) dv = v - 1;
if (u > 0 && v > 0 && u + v > 1)
{
float t = u + v - 1;
du = u - t/2;
dv = v - t/2;
}
VecMulf(e1, du);
VecMulf(e2, dv);
if (Inpf(e1, e1) + Inpf(e2, e2) > threshold * threshold)
{
return 0;
}
if(uv) {
uv[0]= u;
uv[1]= v;
}
return 1;
}
/* Adapted from the paper by Kasper Fauerby */
/* "Improved Collision detection and Response" */
static int getLowestRoot(float a, float b, float c, float maxR, float* root)
@ -4245,6 +4296,67 @@ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float
}
}
/* Intersection point strictly between the two lines
* 0 when no intersection is found
* */
int LineIntersectLineStrict(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda)
{
float a[3], b[3], c[3], ab[3], cb[3], ca[3], dir1[3], dir2[3];
float d;
float d1;
VecSubf(c, v3, v1);
VecSubf(a, v2, v1);
VecSubf(b, v4, v3);
VecCopyf(dir1, a);
Normalize(dir1);
VecCopyf(dir2, b);
Normalize(dir2);
d = Inpf(dir1, dir2);
if (d == 1.0f || d == -1.0f || d == 0) {
/* colinear or one vector is zero-length*/
return 0;
}
d1 = d;
Crossf(ab, a, b);
d = Inpf(c, ab);
/* test if the two lines are coplanar */
if (d > -0.000001f && d < 0.000001f) {
float f1, f2;
Crossf(cb, c, b);
Crossf(ca, c, a);
f1 = Inpf(cb, ab) / Inpf(ab, ab);
f2 = Inpf(ca, ab) / Inpf(ab, ab);
if (f1 >= 0 && f1 <= 1 &&
f2 >= 0 && f2 <= 1)
{
VecMulf(a, f1);
VecAddf(vi, v1, a);
if (lambda != NULL)
{
*lambda = f1;
}
return 1; /* intersection found */
}
else
{
return 0;
}
}
else
{
return 0;
}
}
int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
{
return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&

View File

@ -465,8 +465,6 @@ int subtreeShape(BNode *node, BArc *rootArc, int include_root)
int BLI_subtreeShape(BGraph *graph, BNode *node, BArc *rootArc, int include_root)
{
BNode *test_node;
BLI_flagNodes(graph, 0);
return subtreeShape(node, rootArc, include_root);
}
@ -1033,6 +1031,11 @@ void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit)
BNode *node;
BArc *arc;
if (root_node == NULL)
{
return;
}
if (BLI_isGraphCyclic(graph))
{
return;
@ -1085,3 +1088,56 @@ void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit)
}
}
void* IT_head(void* arg)
{
BArcIterator *iter = (BArcIterator*)arg;
return iter->head(iter);
}
void* IT_tail(void* arg)
{
BArcIterator *iter = (BArcIterator*)arg;
return iter->tail(iter);
}
void* IT_peek(void* arg, int n)
{
BArcIterator *iter = (BArcIterator*)arg;
if (iter->index + n < 0)
{
return iter->head(iter);
}
else if (iter->index + n >= iter->length)
{
return iter->tail(iter);
}
else
{
return iter->peek(iter, n);
}
}
void* IT_next(void* arg)
{
BArcIterator *iter = (BArcIterator*)arg;
return iter->next(iter);
}
void* IT_nextN(void* arg, int n)
{
BArcIterator *iter = (BArcIterator*)arg;
return iter->nextN(iter, n);
}
void* IT_previous(void* arg)
{
BArcIterator *iter = (BArcIterator*)arg;
return iter->previous(iter);
}
int IT_stopped(void* arg)
{
BArcIterator *iter = (BArcIterator*)arg;
return iter->stopped(iter);
}

View File

@ -3477,6 +3477,9 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->imapaint.brush=
newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.brush);
sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
/* Sculptdata textures */
for(a=0; a<MAX_MTEX; ++a) {
MTex *mtex= sce->sculptdata.mtex[a];
@ -7387,28 +7390,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ima->flag |= IMA_DO_PREMUL;
}
}
if (main->versionfile < 245 || main->subversionfile < 12)
{
/* initialize skeleton generation toolsettings */
for(sce=main->scene.first; sce; sce = sce->id.next)
{
sce->toolsettings->skgen_resolution = 50;
sce->toolsettings->skgen_threshold_internal = 0.01f;
sce->toolsettings->skgen_threshold_external = 0.01f;
sce->toolsettings->skgen_angle_limit = 45.0f;
sce->toolsettings->skgen_length_ratio = 1.3f;
sce->toolsettings->skgen_length_limit = 1.5f;
sce->toolsettings->skgen_correlation_limit = 0.98f;
sce->toolsettings->skgen_symmetry_limit = 0.1f;
sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
sce->toolsettings->skgen_postpro_passes = 1;
sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_SUB_CORRELATION;
sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
}
}
}
/* sanity check for skgen
@ -8016,10 +7997,34 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (sce= main->scene.first; sce; sce= sce->id.next) {
sce->toolsettings->imapaint.seam_bleed = 2;
sce->toolsettings->imapaint.normal_angle = 80;
/* initialize skeleton generation toolsettings */
sce->toolsettings->skgen_resolution = 250;
sce->toolsettings->skgen_threshold_internal = 0.1f;
sce->toolsettings->skgen_threshold_external = 0.1f;
sce->toolsettings->skgen_angle_limit = 30.0f;
sce->toolsettings->skgen_length_ratio = 1.3f;
sce->toolsettings->skgen_length_limit = 1.5f;
sce->toolsettings->skgen_correlation_limit = 0.98f;
sce->toolsettings->skgen_symmetry_limit = 0.1f;
sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
sce->toolsettings->skgen_postpro_passes = 3;
sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_FILTER_SMART|SKGEN_SUB_CORRELATION|SKGEN_HARMONIC;
sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
sce->toolsettings->skgen_retarget_angle_weight = 1.0f;
sce->toolsettings->skgen_retarget_length_weight = 1.0f;
sce->toolsettings->skgen_retarget_distance_weight = 1.0f;
/* Skeleton Sketching */
sce->toolsettings->bone_sketching = 0;
sce->toolsettings->skgen_retarget_roll = SK_RETARGET_ROLL_VIEW;
}
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */

View File

@ -0,0 +1,30 @@
/**
* $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.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BDR_SKETCH_H
#define BDR_SKETCH_H
void BDR_queueDrawSketch();
void BDR_drawSketch();
void BDR_drawSketchNames();
#endif /* BDR_SKETCH_H */

View File

@ -68,6 +68,23 @@ typedef struct EditBone
} EditBone;
EditBone *addEditBone(char *name, struct ListBase *ebones, struct bArmature *arm);
/* duplicate method */
void preEditBoneDuplicate(struct ListBase *editbones);
EditBone *duplicateEditBone(EditBone *curBone, char *name, struct ListBase *editbones, struct Object *ob);
void updateDuplicateSubtarget(EditBone *dupBone, struct ListBase *editbones, struct Object *ob);
/* duplicate method (cross objects */
/* editbones is the target list */
EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);
/* editbones is the source list */
void updateDuplicateSubtargetObjects(EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);
/* -- */
float rollBoneToVector(EditBone *bone, float new_up_axis[3]);
void make_boneList(struct ListBase *list, struct ListBase *bones, EditBone *parent);
@ -117,7 +134,7 @@ void selectconnected_posearmature(void);
void armature_select_hierarchy(short direction, short add_to_sel);
void setflag_armature(short mode);
void unique_editbone_name (struct ListBase *ebones, char *name);
void unique_editbone_name (struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */
void auto_align_armature(short mode);
void switch_direction_armature(void);
@ -152,11 +169,15 @@ void align_selected_bones(void);
#define BONESEL_NOSEL 0x80000000 /* Indicates a negative number */
/* from autoarmature */
/* from editarmature_retarget */
void BIF_retargetArmature();
void BIF_adjustRetarget();
void BIF_freeRetarget();
/* from editarmature_sketch */
void BIF_freeSketch();
void BIF_freeTemplates();
struct ReebArc;
float calcVariance(struct ReebArc *arc, int start, int end, float v0[3], float n[3]);
float calcDistance(struct ReebArc *arc, int start, int end, float head[3], float tail[3]);

View File

@ -0,0 +1,44 @@
/**
* $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.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BIF_GENERATE_H
#define BIF_GENERATE_H
struct EditBone;
struct BArcIterator;
struct bArmature;
struct ListBase;
typedef int(NextSubdivisionFunc)(struct BArcIterator*, int, int, float[3], float[3]);
float calcArcCorrelation(struct BArcIterator *iter, int start, int end, float v0[3], float n[3]);
int nextFixedSubdivision(struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
int nextLengthSubdivision(struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
int nextAdaptativeSubdivision(struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
struct EditBone * subdivideArcBy(struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion);
void setBoneRollFromNormal(struct EditBone *bone, float *no, float invmat[][4], float tmat[][3]);
#endif /* BIF_GENERATE_H */

View File

@ -0,0 +1,154 @@
/**
* $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.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BIF_RETARGET_H
#define BIF_RETARGET_H
#include "DNA_listBase.h"
#include "BLI_graph.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
#include "reeb.h"
struct Object;
struct bArmature;
struct EditBone;
struct RigJoint;
struct RigGraph;
struct RigNode;
struct RigArc;
struct RigEdge;
#define USE_THREADS
typedef struct RigGraph {
ListBase arcs;
ListBase nodes;
float length;
FreeArc free_arc;
FreeNode free_node;
RadialSymmetry radial_symmetry;
AxialSymmetry axial_symmetry;
/*********************************/
ListBase controls;
ListBase* editbones;
struct RigNode *head;
ReebGraph *link_mesh;
struct ThreadedWorker *worker;
GHash *bones_map; /* map of editbones by name */
GHash *controls_map; /* map of rigcontrols by bone pointer */
struct Object *ob;
} RigGraph;
typedef struct RigNode {
void *next, *prev;
float p[3];
int flag;
int degree;
struct BArc **arcs;
int subgraph_index;
int symmetry_level;
int symmetry_flag;
float symmetry_axis[3];
/*********************************/
ReebNode *link_mesh;
} RigNode;
typedef struct RigArc {
void *next, *prev;
RigNode *head, *tail;
int flag;
float length;
int symmetry_level;
int symmetry_group;
int symmetry_flag;
/*********************************/
ListBase edges;
int count;
ReebArc *link_mesh;
} RigArc;
typedef struct RigEdge {
struct RigEdge *next, *prev;
float head[3], tail[3];
float length;
float angle; /* angle to next edge */
float up_angle; /* angle between up_axis and the joint normal (defined as Previous edge CrossProduct Current edge */
struct EditBone *bone;
float up_axis[3];
} RigEdge;
/* Control flags */
#define RIG_CTRL_HEAD_DONE 1
#define RIG_CTRL_TAIL_DONE 2
#define RIG_CTRL_PARENT_DEFORM 4
#define RIG_CTRL_FIT_ROOT 8
#define RIG_CTRL_FIT_BONE 16
#define RIG_CTRL_DONE (RIG_CTRL_HEAD_DONE|RIG_CTRL_TAIL_DONE)
/* Control tail flags */
typedef enum {
TL_NONE = 0,
TL_TAIL,
TL_HEAD
} LinkTailMode;
typedef struct RigControl {
struct RigControl *next, *prev;
float head[3], tail[3];
struct EditBone *bone;
struct EditBone *link;
struct EditBone *link_tail;
float up_axis[3];
float offset[3];
float qrot[4]; /* for dual linked bones, store the rotation of the linked bone for the finalization */
int flag;
LinkTailMode tail_mode;
} RigControl;
void BIF_retargetArc(ReebArc *earc, RigGraph *template_rigg);
RigGraph *RIG_graphFromArmature(struct Object *ob, struct bArmature *arm);
int RIG_nbJoints(RigGraph *rg);
char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index);
void RIG_freeRigGraph(BGraph *rg);
#endif /* BIF_RETARGET_H */

View File

@ -0,0 +1,43 @@
/**
* $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.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BIF_SKETCH_H
#define BIF_SKETCH_H
int BIF_paintSketch(short mbut);
void BIF_endStrokeSketch();
void BIF_convertSketch();
void BIF_deleteSketch();
void BIF_selectAllSketch(int mode); /* -1: deselect, 0: select, 1: toggle */
int BIF_validSketchMode();
int BIF_fullSketchMode(); /* full sketch turned on (not Quick) */
void BIF_cancelStrokeSketch();
void BIF_makeListTemplates();
char *BIF_listTemplates();
int BIF_currentTemplate();
void BIF_freeTemplates();
void BIF_setTemplate(int);
int BIF_nbJointsTemplate();
char * BIF_nameBoneTemplate();
#endif /* BIF_SKETCH_H */

View File

@ -54,6 +54,7 @@ struct SpaceOops;
#define VIEW3D_HANDLER_MULTIRES 5
#define VIEW3D_HANDLER_TRANSFORM 6
#define VIEW3D_HANDLER_GREASEPENCIL 7
#define VIEW3D_HANDLER_BONESKETCH 8
/* ipo handler codes */
#define IPO_HANDLER_PROPERTIES 20

View File

@ -86,6 +86,7 @@ struct TransInfo;
struct ScrArea;
struct Base;
struct Scene;
struct Object;
struct TransInfo * BIF_GetTransInfo(void);
void BIF_setSingleAxisConstraint(float vec[3], char *text);
@ -125,5 +126,32 @@ void ManipulatorTransform();
int BIF_do_manipulator(struct ScrArea *sa);
void BIF_draw_manipulator(struct ScrArea *sa);
/* Snapping */
typedef struct DepthPeel
{
struct DepthPeel *next, *prev;
float depth;
float p[3];
float no[3];
struct Object *ob;
int flag;
} DepthPeel;
struct ListBase;
typedef enum SnapMode
{
NOT_SELECTED = 0,
NOT_ACTIVE = 1
} SnapMode;
#define SNAP_MIN_DISTANCE 30
int snapObjects(int *dist, float *loc, float *no, SnapMode mode);
int peelObjects(struct ListBase *depth_peels, short mval[2]);
#endif

View File

@ -28,7 +28,7 @@
#ifndef REEB_H_
#define REEB_H_
//#define WITH_BF_REEB
#define WITH_BF_REEB
#include "DNA_listBase.h"
@ -63,6 +63,7 @@ typedef struct EmbedBucket {
float val;
int nv;
float p[3];
float no[3]; /* if non-null, normal of the bucket */
} EmbedBucket;
typedef struct ReebNode {
@ -79,6 +80,8 @@ typedef struct ReebNode {
int symmetry_flag;
float symmetry_axis[3];
/*********************************/
float no[3];
int index;
float weight;
@ -117,12 +120,23 @@ typedef struct ReebArc {
} ReebArc;
typedef struct ReebArcIterator {
struct ReebArc *arc;
HeadFct head;
TailFct tail;
PeekFct peek;
NextFct next;
NextNFct nextN;
PreviousFct previous;
StoppedFct stopped;
float *p, *no;
int length;
int index;
/*********************************/
struct ReebArc *arc;
int start;
int end;
int stride;
int length;
int stride;
} ReebArcIterator;
struct EditMesh;
@ -139,15 +153,9 @@ void renormalizeWeight(struct EditMesh *em, float newmax);
ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions);
ReebGraph * newReebGraph();
void initArcIterator(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
void initArcIterator2(struct ReebArcIterator *iter, struct ReebArc *arc, int start, int end);
void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
struct EmbedBucket * nextNBucket(ReebArcIterator *iter, int n);
struct EmbedBucket * peekBucket(ReebArcIterator *iter, int n);
struct EmbedBucket * currentBucket(struct ReebArcIterator *iter);
struct EmbedBucket * previousBucket(struct ReebArcIterator *iter);
int iteratorStopped(struct ReebArcIterator *iter);
void initArcIterator(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
void initArcIterator2(BArcIterator *iter, struct ReebArc *arc, int start, int end);
void initArcIteratorStart(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
/* Filtering */
void filterNullReebGraph(ReebGraph *rg);
@ -185,6 +193,7 @@ ReebNode *BIF_lowestLevelNode(ReebNode *node);
ReebGraph *BIF_graphForMultiNode(ReebGraph *rg, ReebNode *node);
void REEB_freeGraph(ReebGraph *rg);
void REEB_freeArc(BArc *barc);
void REEB_exportGraph(ReebGraph *rg, int count);
void REEB_draw();

View File

@ -447,12 +447,20 @@ typedef struct ToolSettings {
char skgen_postpro_passes;
char skgen_subdivisions[3];
char skgen_multi_level;
char skgen_optimisation_method;
char tpad[6];
/* Skeleton Sketching */
struct Object *skgen_template;
char bone_sketching;
char bone_sketching_convert;
char skgen_subdivision_number;
char skgen_retarget_options;
char skgen_retarget_roll;
char skgen_side_string[8];
char skgen_num_string[8];
/* Alt+RMB option */
char edge_mode;
char pad3[2];
} ToolSettings;
/* Used by all brushes to store their properties, which can be directly set
@ -734,6 +742,7 @@ typedef struct Scene {
/* scene->snap_flag */
#define SCE_SNAP 1
#define SCE_SNAP_ROTATE 2
#define SCE_SNAP_PEEL_OBJECT 4
/* scene->snap_target */
#define SCE_SNAP_TARGET_CLOSEST 0
#define SCE_SNAP_TARGET_CENTER 1
@ -743,6 +752,7 @@ typedef struct Scene {
#define SCE_SNAP_MODE_VERTEX 0
#define SCE_SNAP_MODE_EDGE 1
#define SCE_SNAP_MODE_FACE 2
#define SCE_SNAP_MODE_VOLUME 3
/* sce->selectmode */
#define SCE_SELECT_VERTEX 1 /* for mesh */
@ -892,6 +902,25 @@ typedef struct Scene {
#define SKGEN_AVERAGE 1
#define SKGEN_SHARPEN 2
/* toolsettings->bone_sketching */
#define BONE_SKETCHING 1
#define BONE_SKETCHING_QUICK 2
#define BONE_SKETCHING_ADJUST 4
/* toolsettings->bone_sketching_convert */
#define SK_CONVERT_CUT_FIXED 0
#define SK_CONVERT_CUT_LENGTH 1
#define SK_CONVERT_CUT_ADAPTATIVE 2
#define SK_CONVERT_RETARGET 3
/* toolsettings->skgen_retarget_options */
#define SK_RETARGET_AUTONAME 1
/* toolsettings->skgen_retarget_roll */
#define SK_RETARGET_ROLL_VIEW 1
#define SK_RETARGET_ROLL_JOINT 2
#ifdef __cplusplus
}
#endif

View File

@ -280,7 +280,7 @@ static int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value
//create a new editbone
editbone = MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy(editbone->name, key_str, 32);
unique_editbone_name(NULL, editbone->name);
unique_editbone_name(NULL, editbone->name, NULL);
editbone->dist = ((BPy_EditBone*)value)->dist;
editbone->ease1 = ((BPy_EditBone*)value)->ease1;
editbone->ease2 = ((BPy_EditBone*)value)->ease2;

View File

@ -832,7 +832,7 @@ static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds
//otherwise this will act as a py_object
py_editBone->editbone = NULL;
unique_editbone_name(NULL, name);
unique_editbone_name(NULL, name, NULL);
BLI_strncpy(py_editBone->name, name, 32);
py_editBone->parent = NULL;
py_editBone->weight= 1.0f;

View File

@ -5312,7 +5312,6 @@ static void editing_panel_mesh_skgen_retarget(Object *ob, Mesh *me)
uiDefButF(block, NUM, B_DIFF, "Ang:", 1025, 40, 83,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight");
uiDefButF(block, NUM, B_DIFF, "Len:", 1108, 40, 83,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight");
uiDefButF(block, NUM, B_DIFF, "Dist:", 1191, 40, 84,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight");
uiDefButC(block, NUM, B_DIFF, "Method:", 1025, 20, 125,19, &G.scene->toolsettings->skgen_optimisation_method, 0, 2, 1, 0,"Optimisation Method (0: brute, 1: memoize, 2: annealing max fixed");
}
static void editing_panel_mesh_skgen(Object *ob, Mesh *me)

View File

@ -130,6 +130,7 @@
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_sketch.h"
#include "BIF_space.h"
#ifdef WITH_VERSE
@ -143,6 +144,7 @@
#include "BDR_vpaint.h"
#include "BDR_sculptmode.h"
#include "BDR_gpencil.h"
#include "BDR_sketch.h"
#include "BSE_drawview.h"
#include "BSE_filesel.h"
@ -2272,6 +2274,141 @@ static void view3d_panel_transform_spaces(short cntrl)
if(yco < 0) uiNewPanelHeight(block, height-yco);
}
static void delete_sketch_armature(void *arg1, void *arg2)
{
BIF_deleteSketch();
}
static void convert_sketch_armature(void *arg1, void *arg2)
{
BIF_convertSketch();
}
static void assign_template_sketch_armature(void *arg1, void *arg2)
{
int index = *(int*)arg1;
BIF_setTemplate(index);
}
static void view3d_panel_bonesketch_spaces(short cntrl)
{
static int template_index;
static char joint_label[128];
uiBlock *block;
uiBut *but;
char *bone_name;
int yco = 130, height = 140;
int nb_joints;
/* replace with check call to sketching lib */
if (G.obedit && G.obedit->type == OB_ARMATURE)
{
static char subdiv_tooltip[4][64] = {
"Subdivide arcs based on a fixed number of bones",
"Subdivide arcs in bones of equal length",
"Subdivide arcs based on correlation",
"Retarget template to stroke"
};
block= uiNewBlock(&curarea->uiblocks, "view3d_panel_bonesketch_spaces", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(VIEW3D_HANDLER_BONESKETCH); // for close and esc
if(uiNewPanel(curarea, block, "Bone Sketching", "View3d", 10, 230, 250, height)==0) return;
uiNewPanelHeight(block, height);
uiBlockBeginAlign(block);
/* use real flag instead of 1 */
uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones");
uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them");
uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
yco -= 20;
but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
yco -= 20;
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &G.scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)G.scene->toolsettings->bone_sketching_convert]);
switch(G.scene->toolsettings->bone_sketching_convert)
{
case SK_CONVERT_CUT_LENGTH:
uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones");
yco -= 20;
break;
case SK_CONVERT_CUT_ADAPTATIVE:
uiDefButF(block, NUM, B_REDR, "Thres:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision");
yco -= 20;
break;
default:
case SK_CONVERT_CUT_FIXED:
uiDefButC(block, NUM, B_REDR, "Num:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones");
yco -= 20;
break;
case SK_CONVERT_RETARGET:
uiDefButC(block, ROW, B_DIFF, "No", 70, yco, 40,19, &G.scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment");
uiDefButC(block, ROW, B_DIFF, "View", 110, yco, 50,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view");
uiDefButC(block, ROW, B_DIFF, "Joint", 160, yco, 50,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0, "Roll bones relative to joint bend");
yco -= 30;
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
/* button here to select what to do (copy or not), template, ...*/
BIF_makeListTemplates();
template_index = BIF_currentTemplate();
but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
yco -= 20;
uiDefButF(block, NUM, B_DIFF, "A:", 10, yco, 66,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight");
uiDefButF(block, NUM, B_DIFF, "L:", 76, yco, 67,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight");
uiDefButF(block, NUM, B_DIFF, "D:", 143,yco, 67,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight");
yco -= 20;
uiDefBut(block, TEX,B_DIFF,"S:", 10, yco, 90, 20, G.scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with");
uiDefBut(block, TEX,B_DIFF,"N:", 100, yco, 90, 20, G.scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with");
uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_DIFF, ICON_AUTO,190,yco,20,20, &G.scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");
yco -= 20;
/* auto renaming magic */
uiBlockEndAlign(block);
nb_joints = BIF_nbJointsTemplate();
if (nb_joints == -1)
{
nb_joints = G.totvertsel;
}
bone_name = BIF_nameBoneTemplate();
BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
uiDefBut(block, LABEL, 1, joint_label, 10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
yco -= 20;
break;
}
uiBlockEndAlign(block);
uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_DIFF, "Peel Objects", 10, yco, 200, 20, &G.scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
if(yco < 0) uiNewPanelHeight(block, height-yco);
}
}
static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
{
@ -2663,6 +2800,9 @@ static void view3d_blockhandlers(ScrArea *sa)
case VIEW3D_HANDLER_GREASEPENCIL:
view3d_panel_gpencil(v3d->blockhandler[a+1]);
break;
case VIEW3D_HANDLER_BONESKETCH:
view3d_panel_bonesketch_spaces(v3d->blockhandler[a+1]);
break;
}
/* clear action value for event */
v3d->blockhandler[a+1]= 0;
@ -3271,6 +3411,8 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
/* draw grease-pencil stuff */
if (v3d->flag2 & V3D_DISPGP)
draw_gpencil_3dview(sa, 1);
BDR_drawSketch();
persp(PERSP_WIN); // set ortho

View File

@ -99,6 +99,7 @@
#include "BIF_space.h"
#include "BIF_screen.h"
#include "BIF_toolbox.h"
#include "BIF_sketch.h"
#ifdef WITH_VERSE
#include "BIF_verse.h"
@ -1838,7 +1839,11 @@ void mergemenu(void)
void delete_context_selected(void)
{
if(G.obedit) {
if(BIF_fullSketchMode())
{
BIF_deleteSketch();
}
else if(G.obedit) {
if(G.obedit->type==OB_MESH) delete_mesh();
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) delNurb();
else if(G.obedit->type==OB_MBALL) delete_mball();

View File

@ -93,6 +93,7 @@
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BIF_transform.h"
#include "BIF_generate.h"
#include "BDR_editobject.h"
#include "BDR_drawobject.h"
@ -699,7 +700,7 @@ int join_armature(void)
curbone= editbone_name_exists(&eblist, pchan->name);
/* Get new name */
unique_editbone_name(&ebbase, curbone->name);
unique_editbone_name(&ebbase, curbone->name, NULL);
/* Transform the bone */
{
@ -1740,6 +1741,8 @@ void make_editArmature(void)
if (!arm) return;
make_boneList(&G.edbo, &arm->bonebase,NULL);
BIF_freeTemplates(); /* force template update when entering editmode */
}
/* put EditMode back in Object */
@ -1994,17 +1997,14 @@ void undo_push_armature(char *name)
/* **************** END EditMode stuff ********************** */
/* *************** Adding stuff in editmode *************** */
/* default bone add, returns it selected, but without tail set */
static EditBone *add_editbone(char *name)
EditBone *addEditBone(char *name, ListBase *ebones, bArmature *arm)
{
bArmature *arm= G.obedit->data;
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy(bone->name, name, 32);
unique_editbone_name(&G.edbo, bone->name);
unique_editbone_name(ebones, bone->name, NULL);
BLI_addtail(&G.edbo, bone);
BLI_addtail(ebones, bone);
bone->flag |= BONE_TIPSEL;
bone->weight= 1.0F;
@ -2021,6 +2021,14 @@ static EditBone *add_editbone(char *name)
return bone;
}
/* default bone add, returns it selected, but without tail set */
static EditBone *add_editbone(char *name)
{
bArmature *arm= G.obedit->data;
return addEditBone(name, &G.edbo, arm);
}
static void add_primitive_bone(Object *ob, short newob)
{
float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
@ -2192,13 +2200,12 @@ static EditBone *add_points_bone (float head[], float tail[])
return ebo;
}
static EditBone *get_named_editbone(char *name)
static EditBone *get_named_editbone_from_list(char *name, ListBase *editbones)
{
EditBone *eBone;
if (name) {
for (eBone=G.edbo.first; eBone; eBone=eBone->next) {
for (eBone=editbones->first; eBone; eBone=eBone->next) {
if (!strcmp(name, eBone->name))
return eBone;
}
@ -2207,7 +2214,29 @@ static EditBone *get_named_editbone(char *name)
return NULL;
}
static void update_dup_subtarget(EditBone *dupBone)
static EditBone *get_named_editbone(char *name)
{
return get_named_editbone_from_list(name, &G.edbo);
}
/* Call this before doing any duplications
* */
void preEditBoneDuplicate(ListBase *editbones)
{
EditBone *eBone;
/* clear temp */
for (eBone = editbones->first; eBone; eBone = eBone->next)
{
eBone->temp = NULL;
}
}
/*
* Note: When duplicating cross objects, editbones here is the list of bones
* from the SOURCE object but ob is the DESTINATION object
* */
void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Object *src_ob, Object *dst_ob)
{
/* If an edit bone has been duplicated, lets
* update it's constraints if the subtarget
@ -2218,7 +2247,7 @@ static void update_dup_subtarget(EditBone *dupBone)
bConstraint *curcon;
ListBase *conlist;
if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) ) {
if ( (chan = verify_pose_channel(dst_ob->pose, dupBone->name)) ) {
if ( (conlist = &chan->constraints) ) {
for (curcon = conlist->first; curcon; curcon=curcon->next) {
/* does this constraint have a subtarget in
@ -2232,14 +2261,15 @@ static void update_dup_subtarget(EditBone *dupBone)
cti->get_constraint_targets(curcon, &targets);
for (ct= targets.first; ct; ct= ct->next) {
if ((ct->tar == G.obedit) && (ct->subtarget[0])) {
oldtarget = get_named_editbone(ct->subtarget);
if ((ct->tar == src_ob) && (ct->subtarget[0])) {
ct->tar = dst_ob; /* update target */
oldtarget = get_named_editbone_from_list(ct->subtarget, editbones);
if (oldtarget) {
/* was the subtarget bone duplicated too? If
* so, update the constraint to point at the
* duplicate of the old subtarget.
*/
if (oldtarget->flag & BONE_SELECTED){
if (oldtarget->temp){
newtarget = (EditBone *) oldtarget->temp;
strcpy(ct->subtarget, newtarget->name);
}
@ -2255,6 +2285,78 @@ static void update_dup_subtarget(EditBone *dupBone)
}
}
void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob)
{
updateDuplicateSubtargetObjects(dupBone, editbones, ob, ob);
}
EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
{
EditBone *eBone = MEM_callocN(sizeof(EditBone), "addup_editbone");
/* Copy data from old bone to new bone */
memcpy(eBone, curBone, sizeof(EditBone));
curBone->temp = eBone;
eBone->temp = curBone;
if (name != NULL)
{
BLI_strncpy(eBone->name, name, 32);
}
unique_editbone_name(editbones, eBone->name, NULL);
BLI_addtail(editbones, eBone);
/* Lets duplicate the list of constraints that the
* current bone has.
*/
if (src_ob->pose) {
bPoseChannel *chanold, *channew;
ListBase *listold, *listnew;
chanold = verify_pose_channel(src_ob->pose, curBone->name);
if (chanold) {
listold = &chanold->constraints;
if (listold) {
/* WARNING: this creates a new posechannel, but there will not be an attached bone
* yet as the new bones created here are still 'EditBones' not 'Bones'.
*/
channew =
verify_pose_channel(dst_ob->pose, eBone->name);
if (channew) {
/* copy transform locks */
channew->protectflag = chanold->protectflag;
/* copy bone group */
channew->agrp_index= chanold->agrp_index;
/* ik (dof) settings */
channew->ikflag = chanold->ikflag;
VECCOPY(channew->limitmin, chanold->limitmin);
VECCOPY(channew->limitmax, chanold->limitmax);
VECCOPY(channew->stiffness, chanold->stiffness);
channew->ikstretch= chanold->ikstretch;
/* constraints */
listnew = &channew->constraints;
copy_constraints(listnew, listold);
/* custom shape */
channew->custom= chanold->custom;
}
}
}
}
return eBone;
}
EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob)
{
return duplicateEditBoneObjects(curBone, name, editbones, ob, ob);
}
void adduplicate_armature(void)
{
@ -2264,6 +2366,8 @@ void adduplicate_armature(void)
EditBone *firstDup=NULL; /* The beginning of the duplicated bones in the edbo list */
countall(); // flushes selection!
preEditBoneDuplicate(&G.edbo);
/* Select mirrored bones */
if (arm->flag & ARM_MIRROR_EDIT) {
@ -2277,6 +2381,7 @@ void adduplicate_armature(void)
}
}
}
/* Find the selected bones and duplicate them as needed */
for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next) {
@ -2291,7 +2396,7 @@ void adduplicate_armature(void)
curBone->temp = eBone;
eBone->temp = curBone;
unique_editbone_name(&G.edbo, eBone->name);
unique_editbone_name(&G.edbo, eBone->name, NULL);
BLI_addtail(&G.edbo, eBone);
if (!firstDup)
firstDup=eBone;
@ -2351,12 +2456,12 @@ void adduplicate_armature(void)
*/
if (!curBone->parent)
eBone->parent = NULL;
/* If this bone has a parent that IS selected,
/* If this bone has a parent that was duplicated,
Set the duplicate->parent to the curBone->parent->duplicate
*/
else if (curBone->parent->flag & BONE_SELECTED)
else if (curBone->parent->temp)
eBone->parent= (EditBone *)curBone->parent->temp;
/* If this bone has a parent that IS not selected,
/* If this bone has a parent that was not duplicated,
Set the duplicate->parent to the curBone->parent
*/
else {
@ -2366,7 +2471,7 @@ void adduplicate_armature(void)
/* Lets try to fix any constraint subtargets that might
have been duplicated */
update_dup_subtarget(eBone);
updateDuplicateSubtarget(eBone, &G.edbo, OBACT);
}
}
}
@ -3055,13 +3160,16 @@ static EditBone *editbone_name_exists (ListBase *ebones, char *name)
}
/* note: there's a unique_bone_name() too! */
void unique_editbone_name (ListBase *ebones, char *name)
void unique_editbone_name (ListBase *ebones, char *name, EditBone *bone)
{
EditBone *dupli;
char tempname[64];
int number;
char *dot;
if (editbone_name_exists(ebones, name)) {
dupli = editbone_name_exists(ebones, name);
if (dupli && bone != dupli) {
/* Strip off the suffix, if it's a number */
number= strlen(name);
if (number && isdigit(name[number-1])) {
@ -3182,7 +3290,7 @@ void extrude_armature(int forked)
else strcat(newbone->name, "_R");
}
}
unique_editbone_name(&G.edbo, newbone->name);
unique_editbone_name(&G.edbo, newbone->name, NULL);
/* Add the new bone to the list */
BLI_addtail(&G.edbo, newbone);
@ -3269,7 +3377,7 @@ void subdivide_armature(int numcuts)
newbone->flag |= BONE_CONNECTED;
unique_editbone_name (&G.edbo, newbone->name);
unique_editbone_name (&G.edbo, newbone->name, NULL);
/* correct parent bones */
for (tbone = G.edbo.first; tbone; tbone=tbone->next) {
@ -4303,7 +4411,7 @@ void armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
eBone= editbone_name_exists(&G.edbo, oldname);
if (eBone) {
unique_editbone_name(&G.edbo, newname);
unique_editbone_name(&G.edbo, newname, NULL);
BLI_strncpy(eBone->name, newname, MAXBONENAME);
}
else return;
@ -4548,9 +4656,9 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
EditBone *lastBone = NULL;
if (G.scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
{
ReebArcIterator iter;
EmbedBucket *current = NULL;
EmbedBucket *previous = NULL;
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
float *previous = NULL, *current = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
EditBone *root = NULL;
@ -4562,22 +4670,28 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
root = parent;
for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter);
current;
previous = current, current = nextBucket(&iter))
initArcIterator(iter, arc, head);
IT_next(iter);
previous = iter->p;
for (IT_next(iter);
IT_stopped(iter) == 0;
previous = iter->p, IT_next(iter))
{
float vec1[3], vec2[3];
float len1, len2;
current = iter->p;
VecSubf(vec1, previous->p, parent->head);
VecSubf(vec2, current->p, previous->p);
VecSubf(vec1, previous, parent->head);
VecSubf(vec2, current, previous);
len1 = Normalize(vec1);
len2 = Normalize(vec2);
if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit)
{
VECCOPY(parent->tail, previous->p);
VECCOPY(parent->tail, previous);
child = add_editbone("Bone");
VECCOPY(child->head, parent->tail);
@ -4604,179 +4718,26 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
return lastBone;
}
float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
EditBone * test_subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
int len = 2 + abs(end - start);
if (len > 2)
{
ReebArcIterator iter;
EmbedBucket *bucket = NULL;
float avg_t = 0.0f;
float s_t = 0.0f;
float s_xyz = 0.0f;
/* First pass, calculate average */
for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket;
bucket = nextBucket(&iter))
{
float v[3];
VecSubf(v, bucket->p, v0);
avg_t += Inpf(v, n);
}
avg_t /= Inpf(n, n);
avg_t += 1.0f; /* adding start (0) and end (1) values */
avg_t /= len;
/* Second pass, calculate s_xyz and s_t */
for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket;
bucket = nextBucket(&iter))
{
float v[3], d[3];
float dt;
VecSubf(v, bucket->p, v0);
Projf(d, v, n);
VecSubf(v, v, d);
dt = VecLength(d) - avg_t;
s_t += dt * dt;
s_xyz += Inpf(v, v);
}
/* adding start(0) and end(1) values to s_t */
s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
return s_xyz / s_t;
}
else
{
return 0;
}
}
float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3])
{
ReebArcIterator iter;
EmbedBucket *bucket = NULL;
float max_dist = 0;
/* calculate maximum distance */
for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket;
bucket = nextBucket(&iter))
{
float v1[3], v2[3], c[3];
float dist;
VecSubf(v1, head, tail);
VecSubf(v2, bucket->p, tail);
Crossf(c, v1, v2);
dist = Inpf(c, c) / Inpf(v1, v1);
max_dist = dist > max_dist ? dist : max_dist;
}
return max_dist;
}
EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
ReebArcIterator iter;
float n[3];
float ADAPTIVE_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
EditBone *lastBone = NULL;
/* init iterator to get start and end from head */
initArcIterator(&iter, arc, head);
/* Calculate overall */
VecSubf(n, arc->buckets[iter.end].p, head->p);
if (G.scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
{
EmbedBucket *bucket = NULL;
EmbedBucket *previous = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
float normal[3] = {0, 0, 0};
float avg_normal[3];
int total = 0;
int boneStart = iter.start;
float invmat[4][4] = { {1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}};
float tmat[3][3] = { {1, 0, 0},
{0, 1, 0},
{0, 0, 1}};
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
bArmature *arm= G.obedit->data;
parent = add_editbone("Bone");
parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
VECCOPY(parent->head, head->p);
initArcIterator(iter, arc, head);
for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
bucket;
previous = bucket, bucket = nextBucket(&iter))
{
float btail[3];
float value = 0;
if (G.scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
{
VECCOPY(btail, bucket->p);
}
else
{
float length;
/* Calculate normal */
VecSubf(n, bucket->p, parent->head);
length = Normalize(n);
total += 1;
VecAddf(normal, normal, n);
VECCOPY(avg_normal, normal);
VecMulf(avg_normal, 1.0f / total);
VECCOPY(btail, avg_normal);
VecMulf(btail, length);
VecAddf(btail, btail, parent->head);
}
if (G.scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE)
{
value = calcDistance(arc, boneStart, iter.index, parent->head, btail);
}
else
{
float n[3];
VecSubf(n, btail, parent->head);
value = calcVariance(arc, boneStart, iter.index, parent->head, n);
}
if (value > ADAPTIVE_THRESHOLD)
{
VECCOPY(parent->tail, btail);
child = add_editbone("Bone");
VECCOPY(child->head, parent->tail);
child->parent = parent;
child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
parent = child; // new child is next parent
boneStart = iter.index; // start from end
normal[0] = normal[1] = normal[2] = 0;
total = 0;
}
}
VECCOPY(parent->tail, tail->p);
lastBone = parent; /* set last bone in the chain */
lastBone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
}
return lastBone;
@ -4809,107 +4770,26 @@ float arcLengthRatio(ReebArc *arc)
return embedLength / arcLength;
}
EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
EditBone * test_subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
EditBone *lastBone = NULL;
if ((G.scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
{
ReebArcIterator iter;
EmbedBucket *bucket = NULL;
EmbedBucket *previous = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
float lengthLimit = G.scene->toolsettings->skgen_length_limit;
int same = 0;
float invmat[4][4] = { {1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}};
float tmat[3][3] = { {1, 0, 0},
{0, 1, 0},
{0, 0, 1}};
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
bArmature *arm= G.obedit->data;
parent = add_editbone("Bone");
parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
VECCOPY(parent->head, head->p);
initArcIterator(&iter, arc, head);
bucket = nextBucket(&iter);
initArcIterator(iter, arc, head);
while (bucket != NULL)
{
float *vec0 = NULL;
float *vec1 = bucket->p;
/* first bucket. Previous is head */
if (previous == NULL)
{
vec0 = head->p;
}
/* Previous is a valid bucket */
else
{
vec0 = previous->p;
}
/* If lengthLimit hits the current segment */
if (VecLenf(vec1, parent->head) > lengthLimit)
{
if (same == 0)
{
float dv[3], off[3];
float a, b, c, f;
/* Solve quadratic distance equation */
VecSubf(dv, vec1, vec0);
a = Inpf(dv, dv);
VecSubf(off, vec0, parent->head);
b = 2 * Inpf(dv, off);
c = Inpf(off, off) - (lengthLimit * lengthLimit);
f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
//printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
if (isnan(f) == 0 && f < 1.0f)
{
VECCOPY(parent->tail, dv);
VecMulf(parent->tail, f);
VecAddf(parent->tail, parent->tail, vec0);
}
else
{
VECCOPY(parent->tail, vec1);
}
}
else
{
float dv[3];
VecSubf(dv, vec1, vec0);
Normalize(dv);
VECCOPY(parent->tail, dv);
VecMulf(parent->tail, lengthLimit);
VecAddf(parent->tail, parent->tail, parent->head);
}
child = add_editbone("Bone");
VECCOPY(child->head, parent->tail);
child->parent = parent;
child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
parent = child; // new child is next parent
same = 1; // mark as same
}
else
{
previous = bucket;
bucket = nextBucket(&iter);
same = 0; // Reset same
}
}
VECCOPY(parent->tail, tail->p);
lastBone = parent; /* set last bone in the chain */
lastBone = subdivideArcBy(arm, &G.edbo, iter, invmat, tmat, nextLengthSubdivision);
}
return lastBone;
@ -5002,13 +4882,13 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
switch(G.scene->toolsettings->skgen_subdivisions[i])
{
case SKGEN_SUB_LENGTH:
lastBone = subdivideByLength(arc, head, tail);
lastBone = test_subdivideByLength(arc, head, tail);
break;
case SKGEN_SUB_ANGLE:
lastBone = subdivideByAngle(arc, head, tail);
break;
case SKGEN_SUB_CORRELATION:
lastBone = subdivideByCorrelation(arc, head, tail);
lastBone = test_subdivideByCorrelation(arc, head, tail);
break;
}
}

View File

@ -0,0 +1,327 @@
/**
* $Id: editarmature_generate.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., 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 LICENSE BLOCK *****
* editarmature.c: Interface for creating and posing armature objects
*/
#include <string.h>
#include <math.h>
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_graph.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BIF_editarmature.h"
#include "BIF_generate.h"
void setBoneRollFromNormal(EditBone *bone, float *no, float invmat[][4], float tmat[][3])
{
if (no != NULL && !VecIsNull(no))
{
float tangent[3], cotangent[3], normal[3];
VECCOPY(normal, no);
Mat3MulVecfl(tmat, normal);
VecSubf(tangent, bone->tail, bone->head);
Crossf(cotangent, tangent, normal);
Crossf(normal, cotangent, tangent);
Normalize(normal);
bone->roll = rollBoneToVector(bone, normal);
}
}
float calcArcCorrelation(BArcIterator *iter, int start, int end, float v0[3], float n[3])
{
int len = 2 + abs(end - start);
if (len > 2)
{
float avg_t = 0.0f;
float s_t = 0.0f;
float s_xyz = 0.0f;
int i;
/* First pass, calculate average */
for (i = start; i <= end; i++)
{
float v[3];
IT_peek(iter, i);
VecSubf(v, iter->p, v0);
avg_t += Inpf(v, n);
}
avg_t /= Inpf(n, n);
avg_t += 1.0f; /* adding start (0) and end (1) values */
avg_t /= len;
/* Second pass, calculate s_xyz and s_t */
for (i = start; i <= end; i++)
{
float v[3], d[3];
float dt;
IT_peek(iter, i);
VecSubf(v, iter->p, v0);
Projf(d, v, n);
VecSubf(v, v, d);
dt = VecLength(d) - avg_t;
s_t += dt * dt;
s_xyz += Inpf(v, v);
}
/* adding start(0) and end(1) values to s_t */
s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
return 1.0f - s_xyz / s_t;
}
else
{
return 1.0f;
}
}
int nextFixedSubdivision(BArcIterator *iter, int start, int end, float head[3], float p[3])
{
static float stroke_length = 0;
static float current_length;
static char n;
float *v1, *v2;
float length_threshold;
int i;
if (stroke_length == 0)
{
current_length = 0;
IT_peek(iter, start);
v1 = iter->p;
for (i = start + 1; i <= end; i++)
{
IT_peek(iter, i);
v2 = iter->p;
stroke_length += VecLenf(v1, v2);
v1 = v2;
}
n = 0;
current_length = 0;
}
n++;
length_threshold = n * stroke_length / G.scene->toolsettings->skgen_subdivision_number;
IT_peek(iter, start);
v1 = iter->p;
/* < and not <= because we don't care about end, it is P_EXACT anyway */
for (i = start + 1; i < end; i++)
{
IT_peek(iter, i);
v2 = iter->p;
current_length += VecLenf(v1, v2);
if (current_length >= length_threshold)
{
VECCOPY(p, v2);
return i;
}
v1 = v2;
}
stroke_length = 0;
return -1;
}
int nextAdaptativeSubdivision(BArcIterator *iter, int start, int end, float head[3], float p[3])
{
float correlation_threshold = G.scene->toolsettings->skgen_correlation_limit;
float *start_p;
float n[3];
int i;
IT_peek(iter, start);
start_p = iter->p;
for (i = start + 2; i <= end; i++)
{
/* Calculate normal */
IT_peek(iter, i);
VecSubf(n, iter->p, head);
if (calcArcCorrelation(iter, start, i, start_p, n) < correlation_threshold)
{
IT_peek(iter, i - 1);
VECCOPY(p, iter->p);
return i - 1;
}
}
return -1;
}
int nextLengthSubdivision(BArcIterator *iter, int start, int end, float head[3], float p[3])
{
float lengthLimit = G.scene->toolsettings->skgen_length_limit;
int same = 1;
int i;
i = start + 1;
while (i <= end)
{
float *vec0;
float *vec1;
IT_peek(iter, i - 1);
vec0 = iter->p;
IT_peek(iter, i);
vec1 = iter->p;
/* If lengthLimit hits the current segment */
if (VecLenf(vec1, head) > lengthLimit)
{
if (same == 0)
{
float dv[3], off[3];
float a, b, c, f;
/* Solve quadratic distance equation */
VecSubf(dv, vec1, vec0);
a = Inpf(dv, dv);
VecSubf(off, vec0, head);
b = 2 * Inpf(dv, off);
c = Inpf(off, off) - (lengthLimit * lengthLimit);
f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
//printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
if (isnan(f) == 0 && f < 1.0f)
{
VECCOPY(p, dv);
VecMulf(p, f);
VecAddf(p, p, vec0);
}
else
{
VECCOPY(p, vec1);
}
}
else
{
float dv[3];
VecSubf(dv, vec1, vec0);
Normalize(dv);
VECCOPY(p, dv);
VecMulf(p, lengthLimit);
VecAddf(p, p, head);
}
return i - 1; /* restart at lower bound */
}
else
{
i++;
same = 0; // Reset same
}
}
return -1;
}
EditBone * subdivideArcBy(bArmature *arm, ListBase *editbones, BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
{
EditBone *lastBone = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
int bone_start = 0;
int end = iter->length;
int index;
IT_head(iter);
parent = addEditBone("Bone", editbones, arm);
VECCOPY(parent->head, iter->p);
index = next_subdividion(iter, bone_start, end, parent->head, parent->tail);
while (index != -1)
{
IT_peek(iter, index);
child = addEditBone("Bone", editbones, arm);
VECCOPY(child->head, parent->tail);
child->parent = parent;
child->flag |= BONE_CONNECTED;
/* going to next bone, fix parent */
Mat4MulVecfl(invmat, parent->tail);
Mat4MulVecfl(invmat, parent->head);
setBoneRollFromNormal(parent, iter->no, invmat, tmat);
parent = child; // new child is next parent
bone_start = index; // start next bone from current index
index = next_subdividion(iter, bone_start, end, parent->head, parent->tail);
}
iter->tail(iter);
VECCOPY(parent->tail, iter->p);
/* fix last bone */
Mat4MulVecfl(invmat, parent->tail);
Mat4MulVecfl(invmat, parent->head);
setBoneRollFromNormal(parent, iter->no, invmat, tmat);
lastBone = parent;
return lastBone;
}

File diff suppressed because it is too large Load Diff

View File

@ -939,7 +939,7 @@ static void gp_stroke_to_bonechain (bGPDlayer *gpl, bGPDstroke *gps, bArmature *
/* add new bone - note: sync with editarmature.c::add_editbone() */
{
BLI_strncpy(ebo->name, "Stroke", 32);
unique_editbone_name(bones, ebo->name);
unique_editbone_name(bones, ebo->name, NULL);
BLI_addtail(bones, ebo);

View File

@ -3980,6 +3980,9 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
case 22: /* separate */
separate_armature();
break;
case 23: /* bone sketching panel */
add_blockhandler(curarea, VIEW3D_HANDLER_BONESKETCH, UI_PNL_UNSTOW);
break;
}
allqueue(REDRAWVIEW3D, 0);
@ -4057,6 +4060,7 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Bone Sketching|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
@ -5214,6 +5218,7 @@ static char *snapmode_pup(void)
str += sprintf(str, "%s", "|Vertex%x0");
str += sprintf(str, "%s", "|Edge%x1");
str += sprintf(str, "%s", "|Face%x2");
str += sprintf(str, "%s", "|Volume%x3");
return string;
}

View File

@ -850,8 +850,10 @@ void fillArcEmptyBuckets(ReebArc *arc)
static void ExtendArcBuckets(ReebArc *arc)
{
ReebArcIterator iter;
EmbedBucket *previous, *bucket, *last_bucket, *first_bucket;
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
EmbedBucket *last_bucket, *first_bucket;
float *previous = NULL;
float average_length = 0, length;
int padding_head = 0, padding_tail = 0;
@ -860,14 +862,16 @@ static void ExtendArcBuckets(ReebArc *arc)
return; /* failsafe, shouldn't happen */
}
initArcIterator(&iter, arc, arc->head);
initArcIterator(iter, arc, arc->head);
IT_next(iter);
previous = iter->p;
for ( previous = nextBucket(&iter), bucket = nextBucket(&iter);
bucket;
previous = bucket, bucket = nextBucket(&iter)
for ( IT_next(iter);
IT_stopped(iter) == 0;
previous = iter->p, IT_next(iter)
)
{
average_length += VecLenf(previous->p, bucket->p);
average_length += VecLenf(previous, iter->p);
}
average_length /= (arc->bcount - 1);
@ -924,27 +928,24 @@ void extendGraphBuckets(ReebGraph *rg)
void calculateArcLength(ReebArc *arc)
{
ReebArcIterator iter;
EmbedBucket *bucket = NULL;
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
float *vec0, *vec1;
arc->length = 0;
initArcIterator(&iter, arc, arc->head);
initArcIterator(iter, arc, arc->head);
bucket = nextBucket(&iter);
vec0 = arc->head->p;
vec1 = arc->head->p; /* in case there's no embedding */
while (bucket != NULL)
while (IT_next(iter))
{
vec1 = bucket->p;
vec1 = iter->p;
arc->length += VecLenf(vec0, vec1);
vec0 = vec1;
bucket = nextBucket(&iter);
}
arc->length += VecLenf(arc->tail->p, vec1);
@ -997,28 +998,30 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
* */
if (arc1->bcount > 0 && arc2->bcount > 0)
{
ReebArcIterator iter1, iter2;
ReebArcIterator arc_iter1, arc_iter2;
BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
initArcIterator(&iter1, arc1, (ReebNode*)root_node);
initArcIterator(&iter2, arc2, (ReebNode*)root_node);
initArcIterator(iter1, arc1, (ReebNode*)root_node);
initArcIterator(iter2, arc2, (ReebNode*)root_node);
bucket1 = nextBucket(&iter1);
bucket2 = nextBucket(&iter2);
bucket1 = IT_next(iter1);
bucket2 = IT_next(iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
while(bucket1 && bucket2 && bucket1->val < bucket2->val)
{
bucket1 = nextBucket(&iter1);
bucket1 = IT_next(iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
while(bucket1 && bucket2 && bucket2->val < bucket1->val)
{
bucket2 = nextBucket(&iter2);
bucket2 = IT_next(iter2);
}
for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
{
bucket2->nv += bucket1->nv; /* add counts */
@ -1057,28 +1060,30 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
* */
if (arc1->bcount > 0 && arc2->bcount > 0)
{
ReebArcIterator iter1, iter2;
ReebArcIterator arc_iter1, arc_iter2;
BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
initArcIterator(&iter1, arc1, node);
initArcIterator(&iter2, arc2, node);
initArcIterator(iter1, arc1, node);
initArcIterator(iter2, arc2, node);
bucket1 = nextBucket(&iter1);
bucket2 = nextBucket(&iter2);
bucket1 = IT_next(iter1);
bucket2 = IT_next(iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
{
bucket1 = nextBucket(&iter1);
bucket1 = IT_next(iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
{
bucket2 = nextBucket(&iter2);
bucket2 = IT_next(iter2);
}
for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
{
/* copy and mirror back to bucket2 */
bucket2->nv = bucket1->nv;
@ -1116,28 +1121,30 @@ void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BAr
* */
if (arc1->bcount > 0 && arc2->bcount > 0)
{
ReebArcIterator iter1, iter2;
ReebArcIterator arc_iter1, arc_iter2;
BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
initArcIterator(&iter1, arc1, (ReebNode*)root_node);
initArcIterator(&iter2, arc2, (ReebNode*)root_node);
initArcIterator(iter1, arc1, (ReebNode*)root_node);
initArcIterator(iter2, arc2, (ReebNode*)root_node);
bucket1 = nextBucket(&iter1);
bucket2 = nextBucket(&iter2);
bucket1 = IT_next(iter1);
bucket2 = IT_next(iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
{
bucket1 = nextBucket(&iter1);
bucket1 = IT_next(iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
{
bucket2 = nextBucket(&iter2);
bucket2 = IT_next(iter2);
}
for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
{
bucket1->nv += bucket2->nv; /* add counts */
@ -1655,10 +1662,11 @@ int filterInternalExternalReebGraph(ReebGraph *rg, float threshold_internal, flo
middleNode = arc->head;
}
if (middleNode->degree == 2)
if (middleNode->degree == 2 && middleNode != rg->nodes.first)
{
#if 1
// If middle node is a normal node, it will be removed later
// Only if middle node is not the root node
/* USE THIS IF YOU WANT TO PROLONG ARCS TO THEIR TERMINAL NODES
* FOR HANDS, THIS IS NOT THE BEST RESULT
* */
@ -1764,15 +1772,16 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold)
EditFace *efa = BLI_ghashIterator_getValue(&ghi);
#if 0
ReebArcIterator iter;
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
EmbedBucket *bucket = NULL;
EmbedBucket *previous = NULL;
float min_distance = -1;
float angle = 0;
initArcIterator(&iter, arc, arc->head);
initArcIterator(iter, arc, arc->head);
bucket = nextBucket(&iter);
bucket = nextBucket(iter);
while (bucket != NULL)
{
@ -1807,7 +1816,7 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold)
}
previous = bucket;
bucket = nextBucket(&iter);
bucket = nextBucket(iter);
}
avg_angle += saacos(fabs(angle));
@ -3297,8 +3306,44 @@ void arcToVCol(ReebGraph *rg, EditMesh *em, int index)
/****************************************** BUCKET ITERATOR **************************************************/
void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
static void* headNode(void *arg);
static void* tailNode(void *arg);
static void* nextBucket(void *arg);
static void* nextNBucket(void *arg, int n);
static void* peekBucket(void *arg, int n);
static void* previousBucket(void *arg);
static int iteratorStopped(void *arg);
static void initIteratorFct(ReebArcIterator *iter)
{
iter->head = headNode;
iter->tail = tailNode;
iter->peek = peekBucket;
iter->next = nextBucket;
iter->nextN = nextNBucket;
iter->previous = previousBucket;
iter->stopped = iteratorStopped;
}
static void setIteratorValues(ReebArcIterator *iter, EmbedBucket *bucket)
{
if (bucket)
{
iter->p = bucket->p;
iter->no = bucket->no;
}
else
{
iter->p = NULL;
iter->no = NULL;
}
}
void initArcIterator(BArcIterator *arg, ReebArc *arc, ReebNode *head)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
initIteratorFct(iter);
iter->arc = arc;
if (head == arc->head)
@ -3316,11 +3361,14 @@ void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
iter->length = arc->bcount;
iter->index = iter->start - iter->stride;
iter->index = -1;
}
void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start)
void initArcIteratorStart(BArcIterator *arg, struct ReebArc *arc, struct ReebNode *head, int start)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
initIteratorFct(iter);
iter->arc = arc;
if (head == arc->head)
@ -3336,7 +3384,7 @@ void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, str
iter->stride = -1;
}
iter->index = iter->start - iter->stride;
iter->index = -1;
iter->length = arc->bcount - start;
@ -3346,8 +3394,11 @@ void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, str
}
}
void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
void initArcIterator2(BArcIterator *arg, ReebArc *arc, int start, int end)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
initIteratorFct(iter);
iter->arc = arc;
iter->start = start;
@ -3362,76 +3413,120 @@ void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
iter->stride = -1;
}
iter->index = iter->start - iter->stride;
iter->index = -1;
iter->length = abs(iter->end - iter->start) + 1;
}
EmbedBucket * nextBucket(ReebArcIterator *iter)
static void* headNode(void *arg)
{
EmbedBucket *result = NULL;
ReebArcIterator *iter = (ReebArcIterator*)arg;
ReebNode *node;
if (iter->index != iter->end)
if (iter->start < iter->end)
{
iter->index += iter->stride;
result = &(iter->arc->buckets[iter->index]);
}
return result;
}
EmbedBucket * nextNBucket(ReebArcIterator *iter, int n)
{
EmbedBucket *result = NULL;
iter->index += n * iter->stride;
/* check if passed end */
if ((iter->stride == 1 && iter->index <= iter->end) ||
(iter->stride == -1 && iter->index >= iter->end))
{
result = &(iter->arc->buckets[iter->index]);
node = iter->arc->head;
}
else
{
/* stop iterator if passed end */
iter->index = iter->end;
node = iter->arc->tail;
}
iter->p = node->p;
iter->no = node->no;
return node;
}
static void* tailNode(void *arg)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
ReebNode *node;
if (iter->start < iter->end)
{
node = iter->arc->tail;
}
else
{
node = iter->arc->head;
}
iter->p = node->p;
iter->no = node->no;
return node;
}
static void* nextBucket(void *arg)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
iter->index++;
if (iter->index < iter->length)
{
result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
}
setIteratorValues(iter, result);
return result;
}
EmbedBucket * peekBucket(ReebArcIterator *iter, int n)
static void* nextNBucket(void *arg, int n)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
int index = iter->index + n * iter->stride;
iter->index += n;
/* check if passed end */
if ((iter->stride == 1 && index <= iter->end && index >= iter->start) ||
(iter->stride == -1 && index >= iter->end && index <= iter->start))
if (iter->index < iter->length)
{
result = &(iter->arc->buckets[index]);
result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
}
setIteratorValues(iter, result);
return result;
}
EmbedBucket * previousBucket(struct ReebArcIterator *iter)
static void* peekBucket(void *arg, int n)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
int index = iter->index + n;
/* check if passed end */
if (index < iter->length)
{
result = &(iter->arc->buckets[iter->start + (iter->stride * index)]);
}
setIteratorValues(iter, result);
return result;
}
static void* previousBucket(void *arg)
{
ReebArcIterator *iter = (ReebArcIterator*)arg;
EmbedBucket *result = NULL;
if (iter->index != iter->start)
if (iter->index > 0)
{
iter->index -= iter->stride;
result = &(iter->arc->buckets[iter->index]);
iter->index--;
result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
}
setIteratorValues(iter, result);
return result;
}
int iteratorStopped(struct ReebArcIterator *iter)
static int iteratorStopped(void *arg)
{
if (iter->index == iter->end)
ReebArcIterator *iter = (ReebArcIterator*)arg;
if (iter->index >= iter->length)
{
return 1;
}
@ -3441,18 +3536,6 @@ int iteratorStopped(struct ReebArcIterator *iter)
}
}
struct EmbedBucket * currentBucket(struct ReebArcIterator *iter)
{
EmbedBucket *result = NULL;
if (iter->index != iter->end)
{
result = &(iter->arc->buckets[iter->index]);
}
return result;
}
/************************ PUBLIC FUNCTIONS *********************************************/
ReebGraph *BIF_ReebGraphMultiFromEditMesh(void)
@ -3597,26 +3680,32 @@ ReebGraph *BIF_ReebGraphFromEditMesh(void)
rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution);
REEB_exportGraph(rg, -1);
printf("GENERATED\n");
printf("%i subgraphs\n", BLI_FlagSubgraphs((BGraph*)rg));
/* Remove arcs without embedding */
filterNullReebGraph(rg);
BLI_freeAdjacencyList((BGraph*)rg);
/* smart filter and loop filter on basic level */
filterGraph(rg, SKGEN_FILTER_SMART, 0, 0);
printf("NULL FILTERED\n");
printf("%i subgraphs\n", BLI_FlagSubgraphs((BGraph*)rg));
repositionNodes(rg);
/* Filtering might have created degree 2 nodes, so remove them */
removeNormalNodes(rg);
joinSubgraphs(rg, 1.0);
BLI_buildAdjacencyList((BGraph*)rg);
/* calc length before copy, so we have same length on all levels */
BLI_calcGraphLength((BGraph*)rg);
filterGraph(rg, G.scene->toolsettings->skgen_options, G.scene->toolsettings->skgen_threshold_internal, G.scene->toolsettings->skgen_threshold_external);
finalizeGraph(rg, G.scene->toolsettings->skgen_postpro_passes, G.scene->toolsettings->skgen_postpro);
#ifdef DEBUG_REEB
REEB_exportGraph(rg, -1);
#ifdef DEBUG_REEB
arcToVCol(rg, em, 0);
//angleToVCol(em, 1);
#endif
@ -3676,8 +3765,8 @@ void REEB_draw()
glDisable(GL_DEPTH_TEST);
for (arc = rg->arcs.first; arc; arc = arc->next, i++)
{
ReebArcIterator iter;
EmbedBucket *bucket;
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator*)&arc_iter;
float vec[3];
char text[128];
char *s = text;
@ -3689,10 +3778,10 @@ void REEB_draw()
if (arc->bcount)
{
initArcIterator(&iter, arc, arc->head);
for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter))
initArcIterator(iter, arc, arc->head);
for (IT_next(iter); IT_stopped(iter) == 0; IT_next(iter))
{
glVertex3fv(bucket->p);
glVertex3fv(iter->p);
}
}
@ -3722,10 +3811,10 @@ void REEB_draw()
if (arc->bcount)
{
initArcIterator(&iter, arc, arc->head);
for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter))
initArcIterator(iter, arc, arc->head);
for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
{
glVertex3fv(bucket->p);
glVertex3fv(iter->p);
}
}
@ -3743,10 +3832,10 @@ void REEB_draw()
glColor3f(0.5f, 0.5f, 1);
if (arc->bcount)
{
initArcIterator(&iter, arc, arc->head);
for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter))
initArcIterator(iter, arc, arc->head);
for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
{
glVertex3fv(bucket->p);
glVertex3fv(iter->p);
}
}
glEnd();

View File

@ -139,6 +139,7 @@
#include "BIF_toolbox.h"
#include "BIF_usiblender.h"
#include "BIF_previewrender.h"
#include "BIF_sketch.h"
#include "BSE_edit.h"
#include "BSE_view.h"
@ -163,6 +164,7 @@
#include "BDR_sculptmode.h"
#include "BDR_unwrapper.h"
#include "BDR_gpencil.h"
#include "BDR_sketch.h"
#include "BLO_readfile.h" /* for BLO_blendhandle_close */
@ -1263,11 +1265,13 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
* - grease-pencil also defaults to leftmouse
*/
if(event==LEFTMOUSE) {
if(BIF_paintSketch(LEFTMOUSE)) return;
if(gpencil_do_paint(sa, L_MOUSE)) return;
if(BIF_do_manipulator(sa)) return;
}
else if(event==RIGHTMOUSE) {
if(gpencil_do_paint(sa, R_MOUSE)) return;
if(BIF_paintSketch(RIGHTMOUSE)) return;
}
/* swap mouse buttons based on user preference */
@ -1318,6 +1322,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
BDR_queueDrawSketch();
/* Handle retopo painting */
if(retopo_mesh_paint_check()) {
@ -1913,7 +1918,16 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.obedit->type==OB_LATTICE)
deselectall_Latt();
else if(G.obedit->type==OB_ARMATURE)
deselectall_armature(1, 1); /* 1 == toggle */
{
if (BIF_fullSketchMode())
{
BIF_selectAllSketch(1);
}
else
{
deselectall_armature(1, 1); /* 1 == toggle */
}
}
}
else if (ob && (ob->flag & OB_POSEMODE)){
deselectall_posearmature(ob, 1, 1);
@ -1981,6 +1995,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.qual==LR_ALTKEY) {
if(ob && (ob->flag & OB_POSEMODE))
pose_clear_constraints(); /* poseobject.c */
else if (BIF_fullSketchMode())
{
BIF_convertSketch();
}
else
convertmenu(); /* editobject.c */
}
@ -2502,8 +2520,11 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE)
clear_bone_parent();
else if((G.qual==0) && (G.obedit->type==OB_ARMATURE))
armature_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
else if((G.qual==0) && (G.obedit->type==OB_ARMATURE))
{
toggle_blockhandler(curarea, VIEW3D_HANDLER_BONESKETCH, UI_PNL_TO_MOUSE);
allqueue(REDRAWVIEW3D, 0);
}
else if((G.qual==(LR_CTRLKEY|LR_ALTKEY)) && (G.obedit->type==OB_ARMATURE))
separate_armature();
else if((G.qual==0) && G.obedit->type==OB_MESH)
@ -2788,7 +2809,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DELKEY:
if(G.qual==0 || G.qual==LR_SHIFTKEY)
delete_context_selected();
if(G.qual==LR_ALTKEY)
else if(G.qual==LR_ALTKEY)
gpencil_delete_menu();
break;
case YKEY:
@ -2950,7 +2971,11 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case ESCKEY:
if(G.qual==0) {
if (G.qual == 0 && BIF_validSketchMode())
{
BIF_cancelStrokeSketch();
}
else if(G.qual==0) {
if (G.vd->flag & V3D_DISPIMAGE) {
G.vd->flag &= ~V3D_DISPIMAGE;
doredraw= 1;

File diff suppressed because it is too large Load Diff

View File

@ -1109,6 +1109,8 @@ void exit_usiblender(void)
BIF_GlobalReebFree();
BIF_freeRetarget();
BIF_freeTemplates();
BIF_freeSketch();
tf= G.ttfdata.first;
while(tf)

View File

@ -75,6 +75,7 @@
#include "BIF_space.h"
#include "BIF_screen.h"
#include "BIF_toolbox.h"
#include "BIF_sketch.h"
#include "BSE_view.h"
#include "BSE_edit.h" /* For countall */
@ -83,6 +84,7 @@
#include "BDR_drawobject.h" /* For draw_object */
#include "BDR_editface.h" /* For minmax_tface */
#include "BDR_sculptmode.h"
#include "BDR_sketch.h"
#include "mydevice.h"
#include "blendef.h"
@ -1907,7 +1909,14 @@ short view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1
draw_object(BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
}
else if ((G.obedit && G.obedit->type==OB_ARMATURE)) {
draw_object(BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
if (BIF_fullSketchMode())
{
BDR_drawSketchNames();
}
else
{
draw_object(BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
}
}
else {
Base *base;