forked from bartvdbraak/blender
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:
commit
7d2703c805
@ -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;
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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] &&
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,9 +7997,33 @@ 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! */
|
||||
|
30
source/blender/include/BDR_sketch.h
Normal file
30
source/blender/include/BDR_sketch.h
Normal 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 */
|
@ -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]);
|
||||
|
44
source/blender/include/BIF_generate.h
Normal file
44
source/blender/include/BIF_generate.h
Normal 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 */
|
154
source/blender/include/BIF_retarget.h
Normal file
154
source/blender/include/BIF_retarget.h
Normal 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 */
|
43
source/blender/include/BIF_sketch.h
Normal file
43
source/blender/include/BIF_sketch.h
Normal 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 */
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
@ -80,6 +81,8 @@ typedef struct ReebNode {
|
||||
float symmetry_axis[3];
|
||||
/*********************************/
|
||||
|
||||
float no[3];
|
||||
|
||||
int index;
|
||||
float weight;
|
||||
int multi_level;
|
||||
@ -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;
|
||||
} 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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
@ -3272,6 +3412,8 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
|
||||
if (v3d->flag2 & V3D_DISPGP)
|
||||
draw_gpencil_3dview(sa, 1);
|
||||
|
||||
BDR_drawSketch();
|
||||
|
||||
persp(PERSP_WIN); // set ortho
|
||||
|
||||
/* Draw Sculpt Mode brush */
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
@ -2265,6 +2367,8 @@ void adduplicate_armature(void)
|
||||
|
||||
countall(); // flushes selection!
|
||||
|
||||
preEditBoneDuplicate(&G.edbo);
|
||||
|
||||
/* Select mirrored bones */
|
||||
if (arm->flag & ARM_MIRROR_EDIT) {
|
||||
for (curBone=G.edbo.first; curBone; curBone=curBone->next) {
|
||||
@ -2278,6 +2382,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) {
|
||||
if (EBONE_VISIBLE(arm, curBone)) {
|
||||
@ -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;
|
||||
|
||||
VecSubf(vec1, previous->p, parent->head);
|
||||
VecSubf(vec2, current->p, previous->p);
|
||||
current = iter->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);
|
||||
|
||||
initArcIterator(&iter, arc, head);
|
||||
|
||||
bucket = nextBucket(&iter);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
327
source/blender/src/editarmature_generate.c
Normal file
327
source/blender/src/editarmature_generate.c
Normal 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
3073
source/blender/src/editarmature_sketch.c
Normal file
3073
source/blender/src/editarmature_sketch.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
bucket = nextBucket(&iter);
|
||||
initArcIterator(iter, arc, arc->head);
|
||||
|
||||
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();
|
||||
|
@ -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,8 +1918,17 @@ 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)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
@ -2503,7 +2521,10 @@ 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
|
||||
{
|
||||
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
@ -1109,6 +1109,8 @@ void exit_usiblender(void)
|
||||
|
||||
BIF_GlobalReebFree();
|
||||
BIF_freeRetarget();
|
||||
BIF_freeTemplates();
|
||||
BIF_freeSketch();
|
||||
|
||||
tf= G.ttfdata.first;
|
||||
while(tf)
|
||||
|
@ -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,8 +1909,15 @@ 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)) {
|
||||
if (BIF_fullSketchMode())
|
||||
{
|
||||
BDR_drawSketchNames();
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_object(BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Base *base;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user