Merged changes in the trunk up to revision 52191.
Conflicts resolved: source/blender/makesdna/DNA_scene_types.h
This commit is contained in:
@@ -319,8 +319,8 @@ int modifier_dependsOnTime(struct ModifierData *md);
|
||||
int modifier_supportsMapping(struct ModifierData *md);
|
||||
int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md);
|
||||
int modifier_isCorrectableDeformed(struct ModifierData *md);
|
||||
int modifier_sameTopology(ModifierData *md);
|
||||
int modifier_nonGeometrical(ModifierData *md);
|
||||
int modifier_isSameTopology(ModifierData *md);
|
||||
int modifier_isNonGeometrical(ModifierData *md);
|
||||
int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode);
|
||||
void modifier_setError(struct ModifierData *md, const char *format, ...)
|
||||
#ifdef __GNUC__
|
||||
|
||||
@@ -248,7 +248,7 @@ void BKE_sequencer_cache_cleanup(void);
|
||||
struct ImBuf *BKE_sequencer_cache_get(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
|
||||
|
||||
/* passed ImBuf is properly refed, so ownership is *not*
|
||||
* transfered to the cache.
|
||||
* transferred to the cache.
|
||||
* you can pass the same ImBuf multiple times to the cache without problems.
|
||||
*/
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import os
|
||||
|
||||
sources = env.Glob('intern/*.c')
|
||||
sources.remove('intern' + os.sep + 'mask_rasterize.c')
|
||||
sources.remove('intern' + os.sep + 'mask_evaluate.c')
|
||||
sources.remove('intern' + os.sep + 'mask.c')
|
||||
|
||||
sources_mask = env.Glob('intern/mask*.c')
|
||||
|
||||
@@ -1008,8 +1008,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
|
||||
const ColorManagedDisplaySettings *display_settings)
|
||||
{
|
||||
int x, y, c;
|
||||
unsigned int n, nl;
|
||||
double div, divl;
|
||||
unsigned int nl, na, nr, ng, nb;
|
||||
double divl, diva, divr, divg, divb;
|
||||
float *rf = NULL;
|
||||
unsigned char *rc = NULL;
|
||||
unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
|
||||
@@ -1149,24 +1149,37 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
|
||||
savedlines += 1;
|
||||
}
|
||||
|
||||
/* test for nicer distribution even - non standard, leave it out for a while */
|
||||
#if 0
|
||||
for (x = 0; x < 256; x++) {
|
||||
bin_lum[x] = sqrt (bin_lum[x]);
|
||||
bin_r[x] = sqrt(bin_r[x]);
|
||||
bin_g[x] = sqrt(bin_g[x]);
|
||||
bin_b[x] = sqrt(bin_b[x]);
|
||||
bin_a[x] = sqrt(bin_a[x]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* convert hist data to float (proportional to max count) */
|
||||
n = 0;
|
||||
nl = 0;
|
||||
nl = na = nr = nb = ng = 0;
|
||||
for (x = 0; x < 256; x++) {
|
||||
if (bin_lum[x] > nl) nl = bin_lum[x];
|
||||
if (bin_r[x] > n) n = bin_r[x];
|
||||
if (bin_g[x] > n) n = bin_g[x];
|
||||
if (bin_b[x] > n) n = bin_b[x];
|
||||
if (bin_a[x] > n) n = bin_a[x];
|
||||
if (bin_r[x] > nr) nr = bin_r[x];
|
||||
if (bin_g[x] > ng) ng = bin_g[x];
|
||||
if (bin_b[x] > nb) nb = bin_b[x];
|
||||
if (bin_a[x] > na) na = bin_a[x];
|
||||
}
|
||||
div = 1.0 / (double)n;
|
||||
divl = 1.0 / (double)nl;
|
||||
diva = 1.0 / (double)na;
|
||||
divr = 1.0 / (double)nr;
|
||||
divg = 1.0 / (double)ng;
|
||||
divb = 1.0 / (double)nb;
|
||||
for (x = 0; x < 256; x++) {
|
||||
scopes->hist.data_luma[x] = bin_lum[x] * divl;
|
||||
scopes->hist.data_r[x] = bin_r[x] * div;
|
||||
scopes->hist.data_g[x] = bin_g[x] * div;
|
||||
scopes->hist.data_b[x] = bin_b[x] * div;
|
||||
scopes->hist.data_a[x] = bin_a[x] * div;
|
||||
scopes->hist.data_r[x] = bin_r[x] * divr;
|
||||
scopes->hist.data_g[x] = bin_g[x] * divg;
|
||||
scopes->hist.data_b[x] = bin_b[x] * divb;
|
||||
scopes->hist.data_a[x] = bin_a[x] * diva;
|
||||
}
|
||||
MEM_freeN(bin_lum);
|
||||
MEM_freeN(bin_r);
|
||||
|
||||
@@ -671,8 +671,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ob->type == OB_LAMP)
|
||||
else if (ob->type == OB_LAMP) {
|
||||
dag_add_lamp_driver_relations(dag, node, ob->data);
|
||||
}
|
||||
|
||||
/* particles */
|
||||
psys = ob->particlesystem.first;
|
||||
|
||||
@@ -3011,7 +3011,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
|
||||
MLoop *l_iter = loopstart;
|
||||
float area, polynorm_local[3], (*vertexcos)[3];
|
||||
const float *no = polynormal ? polynormal : polynorm_local;
|
||||
BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
|
||||
BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
|
||||
|
||||
/* pack vertex cos into an array for area_poly_v3 */
|
||||
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
|
||||
|
||||
@@ -249,13 +249,13 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md)
|
||||
modifier_supportsMapping(md));
|
||||
}
|
||||
|
||||
int modifier_sameTopology(ModifierData *md)
|
||||
int modifier_isSameTopology(ModifierData *md)
|
||||
{
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
|
||||
}
|
||||
|
||||
int modifier_nonGeometrical(ModifierData *md)
|
||||
int modifier_isNonGeometrical(ModifierData *md)
|
||||
{
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
return (mti->type == eModifierTypeType_NonGeometrical);
|
||||
|
||||
@@ -198,18 +198,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
|
||||
void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
|
||||
{
|
||||
ModifierData *md;
|
||||
BKE_object_free_modifiers(ob);
|
||||
BKE_object_free_modifiers(ob_dst);
|
||||
|
||||
if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
|
||||
if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
|
||||
/* only objects listed above can have modifiers and linking them to objects
|
||||
* which doesn't have modifiers stack is quite silly */
|
||||
return;
|
||||
}
|
||||
|
||||
for (md = from->modifiers.first; md; md = md->next) {
|
||||
for (md = ob_src->modifiers.first; md; md = md->next) {
|
||||
ModifierData *nmd = NULL;
|
||||
|
||||
if (ELEM4(md->type,
|
||||
@@ -221,16 +221,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!BKE_object_support_modifier_type_check(ob, md->type))
|
||||
if (!BKE_object_support_modifier_type_check(ob_dst, md->type))
|
||||
continue;
|
||||
|
||||
nmd = modifier_new(md->type);
|
||||
BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
|
||||
modifier_copyData(md, nmd);
|
||||
BLI_addtail(&ob->modifiers, nmd);
|
||||
BLI_addtail(&ob_dst->modifiers, nmd);
|
||||
modifier_unique_name(&ob_dst->modifiers, nmd);
|
||||
}
|
||||
|
||||
BKE_object_copy_particlesystems(ob, from);
|
||||
BKE_object_copy_softbody(ob, from);
|
||||
BKE_object_copy_particlesystems(ob_dst, ob_src);
|
||||
BKE_object_copy_softbody(ob_dst, ob_src);
|
||||
|
||||
/* TODO: smoke?, cloth? */
|
||||
}
|
||||
|
||||
@@ -139,6 +139,25 @@ MINLINE int power_of_2_min_i(int n)
|
||||
return n;
|
||||
}
|
||||
|
||||
MINLINE unsigned int highest_order_bit_i(unsigned int n)
|
||||
{
|
||||
n |= (n >> 1);
|
||||
n |= (n >> 2);
|
||||
n |= (n >> 4);
|
||||
n |= (n >> 8);
|
||||
n |= (n >> 16);
|
||||
return n - (n >> 1);
|
||||
}
|
||||
|
||||
MINLINE unsigned short highest_order_bit_s(unsigned short n)
|
||||
{
|
||||
n |= (n >> 1);
|
||||
n |= (n >> 2);
|
||||
n |= (n >> 4);
|
||||
n |= (n >> 8);
|
||||
return n - (n >> 1);
|
||||
}
|
||||
|
||||
MINLINE float min_ff(float a, float b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
|
||||
@@ -456,16 +456,50 @@ float BLI_turbulence1(float noisesize, float x, float y, float z, int nr)
|
||||
|
||||
/* ********************* FROM PERLIN HIMSELF: ******************** */
|
||||
|
||||
static char p[512 + 2] = {
|
||||
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
|
||||
0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
|
||||
0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
|
||||
0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
|
||||
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
|
||||
0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
|
||||
0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
|
||||
0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
|
||||
0xA2, 0xA0
|
||||
static const char p[512 + 2] = {
|
||||
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
|
||||
0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
|
||||
0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8,
|
||||
0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
|
||||
0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
|
||||
0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB,
|
||||
0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB,
|
||||
0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
|
||||
0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
|
||||
0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93,
|
||||
0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F,
|
||||
0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
|
||||
0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
|
||||
0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9,
|
||||
0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5,
|
||||
0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
|
||||
0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8,
|
||||
0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4,
|
||||
0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3,
|
||||
0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
|
||||
0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75,
|
||||
0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE,
|
||||
0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
|
||||
0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
|
||||
0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83,
|
||||
0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
|
||||
0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
|
||||
0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
|
||||
0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98,
|
||||
0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
|
||||
0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA,
|
||||
0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
|
||||
0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E,
|
||||
0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
|
||||
0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0,
|
||||
0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
|
||||
0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
|
||||
0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
|
||||
0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8,
|
||||
0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
|
||||
0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
|
||||
0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A,
|
||||
0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -901,7 +901,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
|
||||
|
||||
ob->matbits = MEM_callocN(sizeof(char)*ob->totcol, "ob->matbits");
|
||||
for (a = 0; a < ob->totcol; a++)
|
||||
ob->matbits[a] = ob->colbits & (1<<a);
|
||||
ob->matbits[a] = (ob->colbits & (1<<a)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -244,10 +244,16 @@ enum {
|
||||
# define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
|
||||
#endif
|
||||
|
||||
/* size to use for static arrays when dealing with NGons,
|
||||
/**
|
||||
* size to use for stack arrays when dealing with NGons,
|
||||
* alloc after this limit is reached.
|
||||
* this value is rather arbitrary */
|
||||
#define BM_NGON_STACK_SIZE 32
|
||||
#define BM_DEFAULT_NGON_STACK_SIZE 32
|
||||
/**
|
||||
* size to use for stack arrays dealing with connected mesh data
|
||||
* verts of faces, edges of vert - etc.
|
||||
* often used with #BM_iter_as_arrayN() */
|
||||
#define BM_DEFAULT_ITER_STACK_SIZE 16
|
||||
|
||||
/* avoid inf loop, this value is arbitrary
|
||||
* but should not error on valid cases */
|
||||
|
||||
@@ -174,9 +174,9 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
|
||||
BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
|
||||
{
|
||||
BMEdge **edges2 = NULL;
|
||||
BLI_array_staticdeclare(edges2, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BMVert **verts = NULL;
|
||||
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BMFace *f = NULL;
|
||||
BMEdge *e;
|
||||
BMVert *v, *ev1, *ev2;
|
||||
|
||||
@@ -195,8 +195,8 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
|
||||
{
|
||||
BMVert **verts = NULL;
|
||||
BMEdge **edges = NULL;
|
||||
BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
|
||||
BLI_array_fixedstack_declare(edges, BM_NGON_STACK_SIZE, f->len, __func__);
|
||||
BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
|
||||
BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
BMLoop *l_copy;
|
||||
@@ -558,7 +558,7 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
|
||||
void BM_face_edges_kill(BMesh *bm, BMFace *f)
|
||||
{
|
||||
BMEdge **edges = NULL;
|
||||
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
int i;
|
||||
@@ -582,7 +582,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
|
||||
void BM_face_verts_kill(BMesh *bm, BMFace *f)
|
||||
{
|
||||
BMVert **verts = NULL;
|
||||
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
int i;
|
||||
@@ -734,7 +734,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
|
||||
const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
|
||||
BMLoop *l_iter, *oldprev, *oldnext;
|
||||
BMEdge **edar = NULL;
|
||||
BLI_array_fixedstack_declare(edar, BM_NGON_STACK_SIZE, len, __func__);
|
||||
BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
|
||||
int i, j, edok;
|
||||
|
||||
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
|
||||
@@ -937,9 +937,9 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
|
||||
BMEdge **edges = NULL;
|
||||
BMEdge **deledges = NULL;
|
||||
BMVert **delverts = NULL;
|
||||
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(deledges, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(delverts, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(deledges, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(delverts, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BMVert *v1 = NULL, *v2 = NULL;
|
||||
const char *err = NULL;
|
||||
int i, tote = 0;
|
||||
@@ -1587,7 +1587,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
|
||||
|
||||
if (LIKELY(radlen)) {
|
||||
BMLoop **loops = NULL;
|
||||
BLI_array_fixedstack_declare(loops, BM_NGON_STACK_SIZE, radlen, __func__);
|
||||
BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__);
|
||||
|
||||
killoop = ke->l;
|
||||
|
||||
@@ -1808,23 +1808,28 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
|
||||
*/
|
||||
int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
|
||||
{
|
||||
BMEdge *e;
|
||||
|
||||
void *loops_stack[BM_DEFAULT_ITER_STACK_SIZE];
|
||||
BMLoop **loops;
|
||||
int i, loops_tot;
|
||||
|
||||
BMEdge *e;
|
||||
|
||||
/* verts already spliced */
|
||||
if (v == v_target) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* we can't modify the vert while iterating so first allocate an array of loops */
|
||||
loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot);
|
||||
if (loops) {
|
||||
loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot,
|
||||
loops_stack, BM_DEFAULT_ITER_STACK_SIZE);
|
||||
|
||||
if (LIKELY(loops != NULL)) {
|
||||
for (i = 0; i < loops_tot; i++) {
|
||||
loops[i]->v = v_target;
|
||||
}
|
||||
MEM_freeN(loops);
|
||||
if (loops != (BMLoop **)loops_stack) {
|
||||
MEM_freeN(loops);
|
||||
}
|
||||
}
|
||||
|
||||
/* move all the edges from v's disk to vtarget's disk */
|
||||
|
||||
@@ -231,8 +231,8 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_
|
||||
int vinput_len;
|
||||
int einput_len;
|
||||
|
||||
BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len);
|
||||
BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len);
|
||||
BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len, NULL, 0);
|
||||
BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len, NULL, 0);
|
||||
|
||||
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
|
||||
vinput_arr, vinput_len,
|
||||
|
||||
@@ -174,9 +174,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
|
||||
|
||||
void **blocks = NULL;
|
||||
float (*cos)[3] = NULL, *w = NULL;
|
||||
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
int i;
|
||||
|
||||
BM_elem_attrs_copy(bm, bm, source, target);
|
||||
@@ -613,10 +613,10 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
|
||||
void **vblocks = NULL;
|
||||
float (*cos)[3] = NULL, co[3], *w = NULL;
|
||||
float cent[3] = {0.0f, 0.0f, 0.0f};
|
||||
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(vblocks, BM_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
|
||||
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
|
||||
int i, ax, ay;
|
||||
|
||||
BM_elem_attrs_copy(bm, bm, source, target->f);
|
||||
@@ -689,9 +689,9 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
|
||||
void **blocks = NULL;
|
||||
float (*cos)[3] = NULL, *w = NULL;
|
||||
float cent[3] = {0.0f, 0.0f, 0.0f};
|
||||
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
@@ -116,10 +116,14 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons
|
||||
*
|
||||
* Caller needs to free the array.
|
||||
*/
|
||||
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
|
||||
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
|
||||
/* optional args to avoid an alloc (normally stack array) */
|
||||
void **stack_array, int stack_array_size)
|
||||
{
|
||||
BMIter iter;
|
||||
|
||||
BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
|
||||
|
||||
/* we can't rely on coun't being set */
|
||||
switch (itype) {
|
||||
case BM_VERTS_OF_MESH:
|
||||
@@ -137,7 +141,9 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
|
||||
|
||||
if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
|
||||
BMElem *ele;
|
||||
BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__);
|
||||
BMElem **array = iter.count > stack_array_size ?
|
||||
MEM_mallocN(sizeof(ele) * iter.count, __func__) :
|
||||
stack_array;
|
||||
int i = 0;
|
||||
|
||||
*r_len = iter.count; /* set before iterating */
|
||||
|
||||
@@ -125,7 +125,8 @@ __attribute__((warn_unused_result))
|
||||
#endif
|
||||
;
|
||||
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len);
|
||||
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
|
||||
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
|
||||
void **stack_array, int stack_array_size)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((warn_unused_result))
|
||||
#endif
|
||||
|
||||
@@ -162,7 +162,7 @@ float BM_face_calc_area(BMFace *f)
|
||||
float area;
|
||||
int i;
|
||||
|
||||
BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
|
||||
BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
|
||||
|
||||
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
|
||||
copy_v3_v3(verts[i], l->v->co);
|
||||
@@ -965,8 +965,8 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
|
||||
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
|
||||
int i, j, a = 0, clen;
|
||||
|
||||
BLI_array_fixedstack_declare(projverts, BM_NGON_STACK_SIZE, f->len, "projvertsb");
|
||||
BLI_array_fixedstack_declare(edgeverts, BM_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
|
||||
BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb");
|
||||
BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
|
||||
|
||||
i = 0;
|
||||
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
|
||||
|
||||
@@ -1393,7 +1393,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
|
||||
int BM_face_exists_multi_edge(BMEdge **earr, int len)
|
||||
{
|
||||
BMVert **varr;
|
||||
BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
|
||||
BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
|
||||
|
||||
int ok;
|
||||
int i, i_next;
|
||||
@@ -1419,3 +1419,38 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len)
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* convenience functions for checking flags */
|
||||
int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
|
||||
{
|
||||
return (BM_elem_flag_test(e->v1, hflag) ||
|
||||
BM_elem_flag_test(e->v2, hflag));
|
||||
}
|
||||
|
||||
int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
|
||||
{
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
if (BM_elem_flag_test(l_iter->v, hflag)) {
|
||||
return TRUE;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
|
||||
{
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
if (BM_elem_flag_test(l_iter->e, hflag)) {
|
||||
return TRUE;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -100,4 +100,8 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
|
||||
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
|
||||
BMLoop *edge_loop);
|
||||
|
||||
int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
|
||||
int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
|
||||
int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
|
||||
|
||||
#endif /* __BMESH_QUERIES_H__ */
|
||||
|
||||
@@ -84,6 +84,8 @@ typedef struct VMesh {
|
||||
M_POLY, /* a simple polygon */
|
||||
M_ADJ, /* "adjacent edges" mesh pattern */
|
||||
M_CROSS, /* "cross edges" mesh pattern */
|
||||
M_TRI_FAN, /* a simple polygon - fan filled */
|
||||
M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */
|
||||
} mesh_kind;
|
||||
int count; /* number of vertices in the boundary */
|
||||
int seg; /* common # of segments for segmented edges */
|
||||
@@ -187,10 +189,10 @@ static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e)
|
||||
from_e = &bv->edges[bv->edgecount - 1];
|
||||
e = from_e;
|
||||
do {
|
||||
if (e->isbev)
|
||||
if (e->isbev) {
|
||||
return e;
|
||||
e = e->next;
|
||||
} while (e != from_e);
|
||||
}
|
||||
} while ((e = e->next) != from_e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -384,10 +386,9 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
|
||||
madd_v3_v3fl(off2a, norm_perp2, e2->offset);
|
||||
add_v3_v3v3(off2b, off2a, dir2);
|
||||
|
||||
/* intersect the lines; by construction they should be on the same plane and not parallel */
|
||||
if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
|
||||
BLI_assert(!"offset_meet failure");
|
||||
copy_v3_v3(meetco, off1a); /* just to do something */
|
||||
/* lines are parallel; off1a is a good meet point */
|
||||
copy_v3_v3(meetco, off1a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,8 +441,7 @@ static void project_to_edge(BMEdge *e, float co_a[3], float co_b[3], float projc
|
||||
{
|
||||
float otherco[3];
|
||||
|
||||
if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b,
|
||||
projco, otherco)) {
|
||||
if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b, projco, otherco)) {
|
||||
BLI_assert(!"project meet failure");
|
||||
copy_v3_v3(projco, e->v1->co);
|
||||
}
|
||||
@@ -537,10 +537,10 @@ static void get_point_on_round_edge(EdgeHalf *e, int i,
|
||||
|
||||
get_point_on_round_profile(point, e->offset, i, n, vaadj, vmid, vbadj);
|
||||
|
||||
add_v3_v3v3(p2, profileco, dir);
|
||||
add_v3_v3v3(p2, point, dir);
|
||||
cross_v3_v3v3(pn, vva, vvb);
|
||||
if (!isect_line_plane_v3(profileco, point, p2, vmid, pn, 0)) {
|
||||
BLI_assert(!"bevel: unexpected non-intersection");
|
||||
/* TODO: track down why this sometimes fails */
|
||||
copy_v3_v3(profileco, point);
|
||||
}
|
||||
}
|
||||
@@ -639,10 +639,9 @@ static void build_boundary(BevVert *bv)
|
||||
/* e is not beveled */
|
||||
if (e->next->isbev) {
|
||||
/* next iteration will place e between beveled previous and next edges */
|
||||
e = e->next;
|
||||
continue;
|
||||
/* do nothing... */
|
||||
}
|
||||
if (e->prev->isbev) {
|
||||
else if (e->prev->isbev) {
|
||||
/* on-edge meet between e->prev and e */
|
||||
offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
|
||||
v = add_new_bound_vert(vm, co);
|
||||
@@ -663,16 +662,28 @@ static void build_boundary(BevVert *bv)
|
||||
e->leftv = v;
|
||||
}
|
||||
}
|
||||
e = e->next;
|
||||
} while (e != efirst);
|
||||
} while ((e = e->next) != efirst);
|
||||
|
||||
BLI_assert(vm->count >= 2);
|
||||
if (vm->count == 2 && bv->edgecount == 3)
|
||||
if (vm->count == 2 && bv->edgecount == 3) {
|
||||
vm->mesh_kind = M_NONE;
|
||||
else if (efirst->seg == 1 || bv->selcount < 3)
|
||||
vm->mesh_kind = M_POLY;
|
||||
else
|
||||
vm->mesh_kind = M_ADJ;
|
||||
}
|
||||
else if (efirst->seg == 1 || bv->selcount == 1) {
|
||||
if (vm->count == 3 && bv->selcount == 1) {
|
||||
vm->mesh_kind = M_TRI_FAN;
|
||||
}
|
||||
else {
|
||||
vm->mesh_kind = M_POLY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (bv->selcount == 2) {
|
||||
vm->mesh_kind = M_QUAD_STRIP;
|
||||
}
|
||||
else {
|
||||
vm->mesh_kind = M_ADJ;
|
||||
}
|
||||
}
|
||||
/* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */
|
||||
}
|
||||
|
||||
@@ -694,8 +705,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
ns = vm->seg;
|
||||
ns2 = ns / 2;
|
||||
BLI_assert(n > 2 && ns > 1);
|
||||
|
||||
/* Make initial rings, going between points on neighbors */
|
||||
/* Make initial rings, going between points on neighbors.
|
||||
* After this loop, will have coords for all (i, r, k) where
|
||||
* BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */
|
||||
for (ring = 1; ring <= ns2; ring++) {
|
||||
v = vm->boundstart;
|
||||
do {
|
||||
@@ -732,11 +744,15 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
|
||||
}
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
}
|
||||
|
||||
/* Now make sure cross points of rings share coordinates and vertices */
|
||||
/* Now make sure cross points of rings share coordinates and vertices.
|
||||
* After this loop, will have BMVerts for all (i, r, k) where
|
||||
* i is for a BoundVert that is beveled and has either a predecessor or
|
||||
* successor BoundVert beveled too, and
|
||||
* for odd ns: 0 <= r <= ns2, 0 <= k <= ns
|
||||
* for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */
|
||||
v = vm->boundstart;
|
||||
do {
|
||||
i = v->index;
|
||||
@@ -777,11 +793,13 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
}
|
||||
}
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
|
||||
if (ns % 2 == 0) {
|
||||
/* do special case center lines */
|
||||
/* Do special case center lines.
|
||||
* This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2
|
||||
* and for (i, r, ns2) for 1 <= r <= ns2-1,
|
||||
* whenever i is in a sequence of at least two beveled verts */
|
||||
v = vm->boundstart;
|
||||
do {
|
||||
i = v->index;
|
||||
@@ -807,17 +825,20 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
copy_v3_v3(nv->co, co);
|
||||
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
|
||||
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
|
||||
|
||||
create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v);
|
||||
}
|
||||
else if (vnext->ebev) {
|
||||
mid_v3_v3v3(co, nv->co, nvnext->co);
|
||||
copy_v3_v3(nv->co, co);
|
||||
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
|
||||
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
|
||||
|
||||
create_mesh_bmvert(bm, vm, i, ns2, k, bv->v);
|
||||
}
|
||||
}
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
|
||||
/* center point need to be average of all centers of rings */
|
||||
/* TODO: this is wrong if not all verts have ebev: could have
|
||||
@@ -832,8 +853,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
add_v3_v3(midco, nv->co);
|
||||
nn++;
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
mul_v3_fl(midco, 1.0f / nn);
|
||||
bmv = BM_vert_create(bm, midco, NULL);
|
||||
v = vm->boundstart;
|
||||
@@ -844,8 +864,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
copy_v3_v3(nv->co, midco);
|
||||
nv->v = bmv;
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
}
|
||||
|
||||
/* Make the ring quads */
|
||||
@@ -871,15 +890,19 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
i = v->prev->index;
|
||||
f = boundvert_rep_face(v->prev);
|
||||
for (k = ns2 + (ns % 2); k < ns; k++) {
|
||||
bmv1 = mesh_vert(vm, i, ring + 1, k)->v;
|
||||
bmv2 = mesh_vert(vm, i, ring, k)->v;
|
||||
bmv3 = mesh_vert(vm, i, ring, k + 1)->v;
|
||||
BLI_assert(bmv1 && bmv2 && bmv3);
|
||||
bev_create_quad_tri(bm, bmv1, bmv2, bmv3, NULL, f);
|
||||
bmv1 = mesh_vert(vm, i, ring, k)->v;
|
||||
bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
|
||||
bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
|
||||
bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
|
||||
BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
|
||||
if (bmv2 == bmv3) {
|
||||
bmv3 = bmv4;
|
||||
bmv4 = NULL;
|
||||
}
|
||||
bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
|
||||
}
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
}
|
||||
|
||||
/* Make center ngon if odd number of segments and fully beveled */
|
||||
@@ -892,8 +915,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
i = v->index;
|
||||
BLI_assert(v->ebev);
|
||||
BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
f = boundvert_rep_face(vm->boundstart);
|
||||
bev_create_ngon(bm, vv, BLI_array_count(vv), f);
|
||||
|
||||
@@ -915,21 +937,30 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
if (!v->prev->ebev) {
|
||||
for (k = 0; k < ns2; k++) {
|
||||
bmv1 = mesh_vert(vm, i, ns2, k)->v;
|
||||
if (!bmv1)
|
||||
bmv1 = mesh_vert(vm, i, 0, k)->v;
|
||||
if (!(j > 0 && bmv1 == vv[j - 1])) {
|
||||
BLI_assert(bmv1 != NULL);
|
||||
BLI_array_append(vv, bmv1);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
bmv1 = mesh_vert(vm, i, ns2, ns2)->v;
|
||||
if (!bmv1)
|
||||
bmv1 = mesh_vert(vm, i, 0, ns2)->v;
|
||||
if (!(j > 0 && bmv1 == vv[j - 1])) {
|
||||
BLI_assert(bmv1 != NULL);
|
||||
BLI_array_append(vv, bmv1);
|
||||
j++;
|
||||
}
|
||||
if (!v->next->ebev) {
|
||||
for (k = ns - ns2; k < ns; k++) {
|
||||
bmv1 = mesh_vert(vm, i, ns2, k)->v;
|
||||
if (!bmv1)
|
||||
bmv1 = mesh_vert(vm, i, 0, k)->v;
|
||||
if (!(j > 0 && bmv1 == vv[j - 1])) {
|
||||
BLI_assert(bmv1 != NULL);
|
||||
BLI_array_append(vv, bmv1);
|
||||
j++;
|
||||
}
|
||||
@@ -937,11 +968,11 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL);
|
||||
BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v);
|
||||
j++;
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
if (vv[0] == vv[j - 1])
|
||||
j--;
|
||||
bev_create_ngon(bm, vv, j, f);
|
||||
@@ -950,8 +981,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
||||
}
|
||||
}
|
||||
|
||||
static void bevel_build_poly(BMesh *bm, BevVert *bv)
|
||||
static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
|
||||
{
|
||||
BMFace *f;
|
||||
int n, k;
|
||||
VMesh *vm = bv->vmesh;
|
||||
BoundVert *v;
|
||||
@@ -970,11 +1002,91 @@ static void bevel_build_poly(BMesh *bm, BevVert *bv)
|
||||
n++;
|
||||
}
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
if (n > 2)
|
||||
bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
if (n > 2) {
|
||||
f = bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
|
||||
}
|
||||
else {
|
||||
f = NULL;
|
||||
}
|
||||
BLI_array_free(vv);
|
||||
return f;
|
||||
}
|
||||
|
||||
static void bevel_build_poly(BMesh *bm, BevVert *bv)
|
||||
{
|
||||
bevel_build_poly_ex(bm, bv);
|
||||
}
|
||||
|
||||
static void bevel_build_trifan(BMesh *bm, BevVert *bv)
|
||||
{
|
||||
BMFace *f;
|
||||
BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1);
|
||||
|
||||
f = bevel_build_poly_ex(bm, bv);
|
||||
|
||||
if (f) {
|
||||
/* we have a polygon which we know starts at the previous vertex, make it into a fan */
|
||||
BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev;
|
||||
BMVert *v_fan = l_fan->v;
|
||||
|
||||
while (f->len > 3) {
|
||||
BMLoop *l_new;
|
||||
BMFace *f_new;
|
||||
BLI_assert(v_fan == l_fan->v);
|
||||
f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE);
|
||||
|
||||
if (f_new->len > f->len) {
|
||||
f = f_new;
|
||||
if (l_new->v == v_fan) { l_fan = l_new; }
|
||||
else if (l_new->next->v == v_fan) { l_fan = l_new->next; }
|
||||
else if (l_new->prev->v == v_fan) { l_fan = l_new->prev; }
|
||||
else { BLI_assert(0); }
|
||||
}
|
||||
else {
|
||||
if (l_fan->v == v_fan) { l_fan = l_fan; }
|
||||
else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; }
|
||||
else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; }
|
||||
else { BLI_assert(0); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
|
||||
{
|
||||
BMFace *f;
|
||||
BLI_assert(bv->selcount == 2);
|
||||
|
||||
f = bevel_build_poly_ex(bm, bv);
|
||||
|
||||
if (f) {
|
||||
/* we have a polygon which we know starts at this vertex, make it into strips */
|
||||
BMVert *v_first = bv->vmesh->boundstart->efirst->next->next->leftv->nv.v; /* magic? */
|
||||
//BMLoop *l_start = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_start = BM_face_vert_share_loop(f, v_first);
|
||||
BMLoop *l_a = l_start->prev, *l_a_step;
|
||||
BMLoop *l_b = l_start->next, *l_b_step;
|
||||
|
||||
while (f->len > 4) {
|
||||
// BMLoop *l_new;
|
||||
BMFace *f_new;
|
||||
BLI_assert(l_a->f == f);
|
||||
BLI_assert(l_b->f == f);
|
||||
|
||||
l_a_step = l_a->prev;
|
||||
l_b_step = l_b->next;
|
||||
|
||||
f_new = BM_face_split(bm, f, l_a->v, l_b->v, NULL, NULL, FALSE);
|
||||
|
||||
if (f_new->len > f->len) {
|
||||
f = f_new;
|
||||
}
|
||||
|
||||
l_a = l_a_step;
|
||||
l_b = l_b_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Given that the boundary is built, now make the actual BMVerts
|
||||
@@ -1009,8 +1121,7 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
|
||||
else
|
||||
weld2 = v;
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
|
||||
/* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
|
||||
v = vm->boundstart;
|
||||
@@ -1028,13 +1139,14 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
|
||||
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
|
||||
}
|
||||
}
|
||||
v = v->next;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = v->next) != vm->boundstart);
|
||||
|
||||
if (weld) {
|
||||
vm->mesh_kind = M_NONE;
|
||||
for (k = 1; k < ns; k++) {
|
||||
mid_v3_v3v3(co, mesh_vert(vm, weld1->index, 0, k)->co,
|
||||
mesh_vert(vm, weld2->index, 0, ns - k)->co);
|
||||
va = mesh_vert(vm, weld1->index, 0, k)->co;
|
||||
vb = mesh_vert(vm, weld2->index, 0, ns - k)->co;
|
||||
mid_v3_v3v3(co, va, vb);
|
||||
copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co);
|
||||
create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v);
|
||||
}
|
||||
@@ -1046,6 +1158,10 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
|
||||
bevel_build_rings(bm, bv);
|
||||
else if (vm->mesh_kind == M_POLY)
|
||||
bevel_build_poly(bm, bv);
|
||||
else if (vm->mesh_kind == M_TRI_FAN)
|
||||
bevel_build_trifan(bm, bv);
|
||||
else if (vm->mesh_kind == M_QUAD_STRIP)
|
||||
bevel_build_quadstrip(bm, bv);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1065,10 +1181,14 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMOperator *op, BMV
|
||||
int nsel = 0;
|
||||
|
||||
/* Gather input selected edges.
|
||||
* Only bevel selected edges that have exactly two incident faces. */
|
||||
* Only bevel selected edges that have exactly two incident faces.
|
||||
*
|
||||
* TODO, optimization - we could tag edges in 'geom'
|
||||
* and then just iterate edges-of-vert, checking tags.
|
||||
*/
|
||||
BMO_ITER (bme, &siter, bm, op, "geom", BM_EDGE) {
|
||||
if ((bme->v1 == v) || (BM_edge_other_vert(bme, bme->v1) == v)) {
|
||||
if (BM_edge_face_count(bme) == 2) {
|
||||
if (BM_vert_in_edge(bme, v)) {
|
||||
if (BM_edge_is_manifold(bme)) {
|
||||
BMO_elem_flag_enable(bm, bme, EDGE_SELECTED);
|
||||
nsel++;
|
||||
}
|
||||
@@ -1236,19 +1356,21 @@ static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
|
||||
/* All polygons touching v need rebuilding because beveling v has made new vertices */
|
||||
static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v)
|
||||
{
|
||||
BMFace *f;
|
||||
BMIter iter;
|
||||
void *faces_stack[BM_DEFAULT_ITER_STACK_SIZE];
|
||||
int faces_len, f_index;
|
||||
BMFace **faces = BM_iter_as_arrayN(bm, BM_FACES_OF_VERT, v, &faces_len,
|
||||
faces_stack, BM_DEFAULT_ITER_STACK_SIZE);
|
||||
|
||||
/* TODO: don't iterate through all faces, but just local geometry around v */
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l = f->l_first;
|
||||
do {
|
||||
if (l->v == v) {
|
||||
rebuild_polygon(bm, bp, f);
|
||||
BM_face_kill(bm, f);
|
||||
}
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
if (LIKELY(faces != NULL)) {
|
||||
for (f_index = 0; f_index < faces_len; f_index++) {
|
||||
BMFace *f = faces[f_index];
|
||||
rebuild_polygon(bm, bp, f);
|
||||
BM_face_kill(bm, f);
|
||||
}
|
||||
|
||||
if (faces != (BMFace **)faces_stack) {
|
||||
MEM_freeN(faces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,7 +1388,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
|
||||
BMFace *f1, *f2, *f;
|
||||
int k, nseg, i1, i2;
|
||||
|
||||
if (BM_edge_face_count(bme) != 2)
|
||||
if (!BM_edge_is_manifold(bme))
|
||||
return;
|
||||
|
||||
bv1 = find_bevvert(bp, bme->v1);
|
||||
@@ -1279,12 +1401,12 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
|
||||
|
||||
BLI_assert(e1 && e2);
|
||||
|
||||
/* v4 v3
|
||||
* \ /
|
||||
* e->v1 - e->v2
|
||||
* / \
|
||||
* v1 v2 */
|
||||
|
||||
/* v4 v3
|
||||
* \ /
|
||||
* e->v1 - e->v2
|
||||
* / \
|
||||
* v1 v2
|
||||
*/
|
||||
nseg = e1->seg;
|
||||
BLI_assert(nseg > 0 && nseg == e2->seg);
|
||||
|
||||
@@ -1334,8 +1456,7 @@ static void free_bevel_params(BevelParams *bp)
|
||||
do {
|
||||
vnext = v->next;
|
||||
MEM_freeN(v);
|
||||
v = vnext;
|
||||
} while (v != vm->boundstart);
|
||||
} while ((v = vnext) != vm->boundstart);
|
||||
}
|
||||
if (vm->mesh)
|
||||
MEM_freeN(vm->mesh);
|
||||
@@ -1349,15 +1470,13 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
|
||||
BMOIter siter;
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
BevelParams bp;
|
||||
BevelParams bp = {{NULL}};
|
||||
|
||||
bp.offset = BMO_slot_float_get(op, "offset");
|
||||
bp.op = op;
|
||||
bp.seg = BMO_slot_int_get(op, "segments");
|
||||
|
||||
if (bp.offset > 0) {
|
||||
bp.vertList.first = bp.vertList.last = NULL;
|
||||
|
||||
/* The analysis of the input vertices and execution additional constructions */
|
||||
BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
|
||||
bevel_vert_construct(bm, &bp, op, v);
|
||||
@@ -1563,7 +1682,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
|
||||
BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL);
|
||||
}
|
||||
#if 0
|
||||
if (BM_edge_face_count(e) == 0) {
|
||||
if (BM_edge_is_wire(e)) {
|
||||
BMVert *verts[2] = {e->v1, e->v2};
|
||||
BMEdge *edges[2] = {e, BM_edge_create(bm, e->v1, e->v2, e, 0)};
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ static void rotsys_reverse(BMEdge *UNUSED(e), BMVert *v, EdgeData *edata, VertDa
|
||||
BMEdge **edges = NULL;
|
||||
BMEdge *e_first;
|
||||
BMEdge *e;
|
||||
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
int i, totedge;
|
||||
|
||||
e = e_first = vdata[BM_elem_index_get(v)].e;
|
||||
@@ -359,10 +359,10 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
BMEdge **edges = NULL;
|
||||
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
BMVert *v;
|
||||
/* BMVert **verts = NULL; */
|
||||
/* BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE); */ /* UNUSE */
|
||||
/* BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); */ /* UNUSE */
|
||||
int i;
|
||||
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
|
||||
@@ -595,10 +595,10 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
|
||||
|
||||
/* array for passing verts to angle_poly_v3 */
|
||||
float **verts = NULL;
|
||||
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
/* array for receiving angles from angle_poly_v3 */
|
||||
float *face_angles = NULL;
|
||||
BLI_array_staticdeclare(face_angles, BM_NGON_STACK_SIZE);
|
||||
BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE);
|
||||
|
||||
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
||||
|
||||
|
||||
@@ -385,7 +385,7 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
|
||||
BMO_ITER (f, &oiter, bm, op, "input", BM_FACE) {
|
||||
if (BMO_elem_flag_test(bm, f, HULL_FLAG_HOLE)) {
|
||||
BM_ITER_ELEM (e, &iter, f, BM_EDGES_OF_FACE) {
|
||||
if (BM_edge_face_count(e) == 1) {
|
||||
if (BM_edge_is_boundary(e)) {
|
||||
BMO_elem_flag_disable(bm, f, HULL_FLAG_HOLE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
|
||||
}
|
||||
|
||||
/* apply the new difference to the rest of the shape keys,
|
||||
* note that this doent take rotations into account, we _could_ support
|
||||
* note that this dosn't take rotations into account, we _could_ support
|
||||
* this by getting the normals and coords for each shape key and
|
||||
* re-calculate the smooth value for each but this is quite involved.
|
||||
* for now its ok to simply apply the difference IMHO - campbell */
|
||||
|
||||
@@ -617,7 +617,7 @@ static void symm_kill_unused(Symm *symm)
|
||||
!symmetric)
|
||||
{
|
||||
/* The edge might be used by a face outside the input set */
|
||||
if (BM_edge_face_count(e) == 0)
|
||||
if (BM_edge_is_wire(e))
|
||||
BM_edge_kill(symm->bm, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,7 +844,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
|
||||
* This function returns the aspet ration from the Collada camera.
|
||||
*
|
||||
* Note:COLLADA allows to specify either XFov, or YFov alone.
|
||||
* In tghat case the aspect ratio can be determined from
|
||||
* In that case the aspect ratio can be determined from
|
||||
* the viewport aspect ratio (which is 1:1 ?)
|
||||
* XXX: check this: its probably wrong!
|
||||
* If both values are specified, then the aspect ration is simply xfov/yfov
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
class PixelateOperation : public NodeOperation {
|
||||
private:
|
||||
/**
|
||||
* @brief cached refeerence to the input operation
|
||||
* @brief cached reference to the input operation
|
||||
*/
|
||||
SocketReader *m_inputOperation;
|
||||
public:
|
||||
|
||||
@@ -139,11 +139,11 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
|
||||
return &sseq->gpd;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SPACE_IMAGE: /* Image/UV Editor */
|
||||
{
|
||||
SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
|
||||
|
||||
|
||||
/* for now, Grease Pencil data is associated with the space... */
|
||||
/* XXX our convention for everything else is to link to data though... */
|
||||
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
|
||||
@@ -159,19 +159,19 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
|
||||
if (clip) {
|
||||
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
|
||||
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
|
||||
|
||||
|
||||
if (!track)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (ptr)
|
||||
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
|
||||
|
||||
|
||||
return &track->gpd;
|
||||
}
|
||||
else {
|
||||
if (ptr)
|
||||
RNA_id_pointer_create(&clip->id, ptr);
|
||||
|
||||
|
||||
return &clip->gpd;
|
||||
}
|
||||
}
|
||||
@@ -471,7 +471,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
|
||||
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* convert screen coordinate to 3d coordinates
|
||||
* - method taken from editview.c - mouse_cursor()
|
||||
*/
|
||||
@@ -504,19 +504,22 @@ typedef struct tGpTimingData {
|
||||
double inittime;
|
||||
} tGpTimingData;
|
||||
|
||||
/* init point buffers for timing data */
|
||||
static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
|
||||
{
|
||||
float *tmp;
|
||||
|
||||
BLI_assert(nbr > gtd->num_points);
|
||||
|
||||
|
||||
/* distances */
|
||||
tmp = gtd->dists;
|
||||
gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
|
||||
if (tmp) {
|
||||
memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
|
||||
MEM_freeN(tmp);
|
||||
}
|
||||
|
||||
|
||||
/* times */
|
||||
tmp = gtd->times;
|
||||
gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
|
||||
if (tmp) {
|
||||
@@ -527,20 +530,28 @@ static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
|
||||
gtd->num_points = nbr;
|
||||
}
|
||||
|
||||
/* add stroke point to timing buffers */
|
||||
static void gp_timing_data_add_point(tGpTimingData *gtd, double stroke_inittime, float time, float delta_dist)
|
||||
{
|
||||
if (time < 0.0f) {
|
||||
/* This is a gap, negative value! */
|
||||
gtd->tot_time = -(gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time));
|
||||
gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time);
|
||||
gtd->tot_time = -gtd->times[gtd->cur_point];
|
||||
|
||||
gtd->gap_tot_time += gtd->times[gtd->cur_point] - gtd->times[gtd->cur_point - 1];
|
||||
}
|
||||
else
|
||||
gtd->tot_time = (gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time));
|
||||
gtd->dists[gtd->cur_point] = (gtd->tot_dist += delta_dist);
|
||||
else {
|
||||
gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time);
|
||||
gtd->tot_time = (gtd->times[gtd->cur_point]);
|
||||
}
|
||||
|
||||
gtd->tot_dist += delta_dist;
|
||||
gtd->dists[gtd->cur_point] = gtd->tot_dist;
|
||||
|
||||
gtd->cur_point++;
|
||||
}
|
||||
|
||||
/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we can’t set
|
||||
/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we can't set
|
||||
* arbitrarily close points - this is esp. important with NoGaps mode!
|
||||
*/
|
||||
#define MIN_TIME_DELTA 0.02f
|
||||
@@ -550,7 +561,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps,
|
||||
float tot_gaps_time, float delta_time, float *next_delta_time)
|
||||
{
|
||||
int j;
|
||||
|
||||
|
||||
for (j = idx + 1; j < gtd->num_points; j++) {
|
||||
if (gtd->times[j] < 0) {
|
||||
gtd->times[j] = -gtd->times[j];
|
||||
@@ -562,20 +573,23 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps,
|
||||
/* We want gaps that are in gtd->gap_duration +/- gtd->gap_randomness range,
|
||||
* and which sum to exactly tot_gaps_time...
|
||||
*/
|
||||
int rem_gaps = nbr_gaps - *nbr_done_gaps;
|
||||
int rem_gaps = nbr_gaps - (*nbr_done_gaps);
|
||||
if (rem_gaps < 2) {
|
||||
/* Last gap, just give remaining time! */
|
||||
*next_delta_time = tot_gaps_time;
|
||||
}
|
||||
else {
|
||||
float delta, min, max;
|
||||
|
||||
/* This code ensures that if the first gaps have been shorter than average gap_duration,
|
||||
* next gaps will tend to be longer (i.e. try to recover the lateness), and vice-versa!
|
||||
*/
|
||||
delta = delta_time - (gtd->gap_duration * *nbr_done_gaps);
|
||||
delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
|
||||
|
||||
/* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
|
||||
min = -gtd->gap_randomness - delta;
|
||||
CLAMP(min, -gtd->gap_randomness, 0.0f);
|
||||
|
||||
/* Clamp max between [0.0, gap_randomness], with lower delta giving higher max */
|
||||
max = gtd->gap_randomness - delta;
|
||||
CLAMP(max, 0.0f, gtd->gap_randomness);
|
||||
@@ -655,11 +669,11 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR
|
||||
/* This one should *never* be negative! */
|
||||
end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
|
||||
}
|
||||
|
||||
|
||||
/* Simple proportional stuff... */
|
||||
cu->ctime = gtd->dists[i] / gtd->tot_dist * cu->pathlen;
|
||||
cfra = time_start + ((gtd->times[i] + delta_time) / gtd->tot_time * time_range);
|
||||
|
||||
|
||||
/* And now, the checks about timing... */
|
||||
if (i == start_stroke_idx) {
|
||||
/* If first point of a stroke, be sure it's enough ahead of last valid keyframe, and
|
||||
@@ -709,45 +723,44 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
|
||||
FCurve *fcu;
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop = NULL;
|
||||
|
||||
int nbr_gaps = 0, i;
|
||||
|
||||
|
||||
if (gtd->mode == GP_STROKECONVERT_TIMING_NONE)
|
||||
return;
|
||||
|
||||
|
||||
/* gap_duration and gap_randomness are in frames, but we need seconds!!! */
|
||||
gtd->gap_duration = FRA2TIME(gtd->gap_duration);
|
||||
gtd->gap_randomness = FRA2TIME(gtd->gap_randomness);
|
||||
|
||||
|
||||
/* Enable path! */
|
||||
cu->flag |= CU_PATH;
|
||||
cu->pathlen = gtd->frame_range;
|
||||
|
||||
/* Get or create default action to add F-Curve+keyframe to */
|
||||
act = verify_adt_action((ID*)cu, TRUE);
|
||||
/* Create RNA stuff */
|
||||
RNA_id_pointer_create((ID*)cu, &ptr);
|
||||
|
||||
/* Get RNA pointer to read/write path time values */
|
||||
RNA_id_pointer_create((ID *)cu, &ptr);
|
||||
prop = RNA_struct_find_property(&ptr, "eval_time");
|
||||
/* Get or create fcurve */
|
||||
|
||||
/* Ensure we have an F-Curve to add keyframes to */
|
||||
act = verify_adt_action((ID *)cu, TRUE);
|
||||
fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, TRUE);
|
||||
|
||||
|
||||
if (G.debug & G_DEBUG) {
|
||||
printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
|
||||
for (i = 0; i < gtd->num_points; i++) {
|
||||
printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
|
||||
float cfra;
|
||||
|
||||
|
||||
/* Linear extrapolation! */
|
||||
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
|
||||
|
||||
|
||||
cu->ctime = 0.0f;
|
||||
cfra = (float)gtd->start_frame;
|
||||
insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
|
||||
|
||||
|
||||
cu->ctime = cu->pathlen;
|
||||
if (gtd->realtime) {
|
||||
cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
|
||||
@@ -760,34 +773,33 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
|
||||
else {
|
||||
/* Use actual recorded timing! */
|
||||
float time_range;
|
||||
|
||||
|
||||
/* CustomGaps specific */
|
||||
float tot_gaps_time = 0.0f;
|
||||
|
||||
/* Pre-process gaps, in case we don't want to keep their org timing */
|
||||
|
||||
/* Pre-process gaps, in case we don't want to keep their original timing */
|
||||
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
|
||||
gp_stroke_path_animation_preprocess_gaps(gtd, &nbr_gaps, &tot_gaps_time);
|
||||
}
|
||||
|
||||
|
||||
if (gtd->realtime) {
|
||||
time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
|
||||
}
|
||||
else {
|
||||
time_range = (float)(gtd->end_frame - gtd->start_frame);
|
||||
}
|
||||
|
||||
|
||||
if (G.debug & G_DEBUG) {
|
||||
printf("Starting keying!\n");
|
||||
printf("GP Stroke Path Conversion: Starting keying!\n");
|
||||
}
|
||||
|
||||
|
||||
gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, time_range,
|
||||
nbr_gaps, tot_gaps_time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */
|
||||
calchandles_fcurve(fcu);
|
||||
|
||||
|
||||
if (G.debug & G_DEBUG) {
|
||||
printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
|
||||
for (i = 0; i < gtd->num_points; i++) {
|
||||
@@ -795,11 +807,11 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
|
||||
|
||||
|
||||
/* send updates */
|
||||
DAG_id_tag_update((ID*)cu, 0);
|
||||
DAG_id_tag_update(&cu->id, 0);
|
||||
}
|
||||
|
||||
#undef MIN_TIME_DELTA
|
||||
@@ -813,14 +825,15 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
Nurb *nu = curnu ? *curnu : NULL;
|
||||
Nurb *nu = (curnu) ? *curnu : NULL;
|
||||
BPoint *bp, *prev_bp = NULL;
|
||||
int i, old_nbp = 0;
|
||||
const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
|
||||
int i, old_nbp = 0;
|
||||
|
||||
/* create new 'nurb' or extend current one within the curve */
|
||||
if (nu) {
|
||||
old_nbp = nu->pntsu;
|
||||
|
||||
/* If stitch, the first point of this stroke is already present in current nu.
|
||||
* Else, we have to add to additional points to make the zero-radius link between strokes.
|
||||
*/
|
||||
@@ -837,9 +850,9 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
nu->resolu = cu->resolu;
|
||||
nu->resolv = cu->resolv;
|
||||
nu->knotsu = NULL;
|
||||
|
||||
|
||||
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
|
||||
|
||||
|
||||
stitch = FALSE; /* Security! */
|
||||
}
|
||||
|
||||
@@ -861,11 +874,12 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
float delta_time;
|
||||
|
||||
prev_bp = NULL;
|
||||
if (old_nbp > 1 && gps->prev && gps->prev->totpoints > 1) {
|
||||
if ((old_nbp > 1) && gps->prev && (gps->prev->totpoints > 1)) {
|
||||
/* Only use last curve segment if previous stroke was not a single-point one! */
|
||||
prev_bp = nu->bp + old_nbp - 2;
|
||||
}
|
||||
bp = nu->bp + old_nbp - 1;
|
||||
|
||||
/* XXX We do this twice... Not sure it's worth to bother about this! */
|
||||
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
|
||||
if (prev_bp) {
|
||||
@@ -874,6 +888,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
else {
|
||||
interp_v3_v3v3(p1, bp->vec, p, GAP_DFAC);
|
||||
}
|
||||
|
||||
if (gps->totpoints > 1) {
|
||||
/* XXX We do this twice... Not sure it's worth to bother about this! */
|
||||
gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
|
||||
@@ -882,7 +897,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
else {
|
||||
interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC);
|
||||
}
|
||||
|
||||
|
||||
/* First point */
|
||||
bp++;
|
||||
copy_v3_v3(bp->vec, p1);
|
||||
@@ -898,7 +913,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
}
|
||||
gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bp - 1)->vec, p1));
|
||||
}
|
||||
|
||||
|
||||
/* Second point */
|
||||
bp++;
|
||||
copy_v3_v3(bp->vec, p2);
|
||||
@@ -915,25 +930,26 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
}
|
||||
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
|
||||
}
|
||||
|
||||
|
||||
old_nbp += 2;
|
||||
}
|
||||
if (old_nbp && do_gtd) {
|
||||
prev_bp = nu->bp + old_nbp - 1;
|
||||
}
|
||||
|
||||
/* add points */
|
||||
for (i = stitch ? 1 : 0, pt = gps->points + (stitch ? 1 : 0), bp = nu->bp + old_nbp;
|
||||
for (i = (stitch) ? 1 : 0, pt = gps->points + ((stitch) ? 1 : 0), bp = nu->bp + old_nbp;
|
||||
i < gps->totpoints;
|
||||
i++, pt++, bp++)
|
||||
{
|
||||
float p3d[3];
|
||||
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
|
||||
|
||||
|
||||
/* get coordinates to add at */
|
||||
gp_strokepoint_convertcoords(C, gps, pt, p3d, subrect);
|
||||
copy_v3_v3(bp->vec, p3d);
|
||||
bp->vec[3] = 1.0f;
|
||||
|
||||
|
||||
/* set settings */
|
||||
bp->f1 = SELECT;
|
||||
bp->radius = width * rad_fac;
|
||||
@@ -945,14 +961,14 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
else if (bp->weight > minmax_weights[1]) {
|
||||
minmax_weights[1] = bp->weight;
|
||||
}
|
||||
|
||||
|
||||
/* Update timing data */
|
||||
if (do_gtd) {
|
||||
gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bp ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
|
||||
gp_timing_data_add_point(gtd, gps->inittime, pt->time, (prev_bp) ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
|
||||
}
|
||||
prev_bp = bp;
|
||||
}
|
||||
|
||||
|
||||
/* add nurb to curve */
|
||||
if (!curnu || !*curnu) {
|
||||
BLI_addtail(&cu->nurb, nu);
|
||||
@@ -960,7 +976,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
if (curnu) {
|
||||
*curnu = nu;
|
||||
}
|
||||
|
||||
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
}
|
||||
|
||||
@@ -968,7 +984,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
|
||||
if (v3d) {
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
|
||||
@@ -979,7 +995,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -988,12 +1004,12 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
Nurb *nu = curnu ? *curnu : NULL;
|
||||
Nurb *nu = (curnu) ? *curnu : NULL;
|
||||
BezTriple *bezt, *prev_bezt = NULL;
|
||||
int i, tot, old_nbezt = 0;
|
||||
float p3d_cur[3], p3d_prev[3], p3d_next[3];
|
||||
const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
|
||||
|
||||
|
||||
/* create new 'nurb' or extend current one within the curve */
|
||||
if (nu) {
|
||||
old_nbezt = nu->pntsu;
|
||||
@@ -1001,17 +1017,17 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
* so no need to add it.
|
||||
* If no stitch, we want to add two additional points to make a "zero-radius" link between both strokes.
|
||||
*/
|
||||
BKE_nurb_bezierPoints_add(nu, gps->totpoints + (stitch ? -1 : 2));
|
||||
BKE_nurb_bezierPoints_add(nu, gps->totpoints + ((stitch) ? -1 : 2));
|
||||
}
|
||||
else {
|
||||
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
|
||||
|
||||
|
||||
nu->pntsu = gps->totpoints;
|
||||
nu->resolu = 12;
|
||||
nu->resolv = 12;
|
||||
nu->type = CU_BEZIER;
|
||||
nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints * sizeof(BezTriple), "bezts");
|
||||
|
||||
|
||||
stitch = FALSE; /* Security! */
|
||||
}
|
||||
|
||||
@@ -1024,9 +1040,9 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
/* get initial coordinates */
|
||||
pt = gps->points;
|
||||
if (tot) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt, stitch ? p3d_prev : p3d_cur, subrect);
|
||||
gp_strokepoint_convertcoords(C, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
|
||||
if (tot > 1) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 1, stitch ? p3d_cur : p3d_next, subrect);
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
|
||||
}
|
||||
if (stitch && tot > 2) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
|
||||
@@ -1035,7 +1051,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
|
||||
/* If needed, make the link between both strokes with two zero-radius additional points */
|
||||
if (curnu && old_nbezt) {
|
||||
/* Update last point's second handle! */
|
||||
/* Update last point's second handle */
|
||||
if (stitch) {
|
||||
float h2[3];
|
||||
bezt = nu->bezt + old_nbezt - 1;
|
||||
@@ -1043,6 +1059,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
copy_v3_v3(bezt->vec[2], h2);
|
||||
pt++;
|
||||
}
|
||||
|
||||
/* Create "link points" */
|
||||
/* About "zero-radius" point interpolations:
|
||||
* - If we have at least two points in current curve (most common case), we linearly extrapolate
|
||||
@@ -1055,7 +1072,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
else {
|
||||
float h1[3], h2[3], p1[3], p2[3];
|
||||
float delta_time;
|
||||
|
||||
|
||||
prev_bezt = NULL;
|
||||
if (old_nbezt > 1 && gps->prev && gps->prev->totpoints > 1) {
|
||||
/* Only use last curve segment if previous stroke was not a single-point one! */
|
||||
@@ -1074,15 +1091,15 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
else {
|
||||
interp_v3_v3v3(p2, p3d_cur, bezt->vec[1], GAP_DFAC);
|
||||
}
|
||||
|
||||
|
||||
/* Second handle of last point */
|
||||
interp_v3_v3v3(h2, bezt->vec[1], p1, BEZT_HANDLE_FAC);
|
||||
copy_v3_v3(bezt->vec[2], h2);
|
||||
|
||||
|
||||
/* First point */
|
||||
interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
|
||||
interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
|
||||
|
||||
|
||||
bezt++;
|
||||
copy_v3_v3(bezt->vec[0], h1);
|
||||
copy_v3_v3(bezt->vec[1], p1);
|
||||
@@ -1090,7 +1107,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
bezt->h1 = bezt->h2 = HD_FREE;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
|
||||
minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
|
||||
|
||||
|
||||
if (do_gtd) {
|
||||
if (prev_bezt) {
|
||||
delta_time = gtd->tot_time + (gtd->tot_time - gtd->times[gtd->cur_point - 1]) * GAP_DFAC;
|
||||
@@ -1100,11 +1117,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
}
|
||||
gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bezt - 1)->vec[1], p1));
|
||||
}
|
||||
|
||||
|
||||
/* Second point */
|
||||
interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
|
||||
interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
|
||||
|
||||
|
||||
bezt++;
|
||||
copy_v3_v3(bezt->vec[0], h1);
|
||||
copy_v3_v3(bezt->vec[1], p2);
|
||||
@@ -1112,7 +1129,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
bezt->h1 = bezt->h2 = HD_FREE;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
|
||||
minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
|
||||
|
||||
|
||||
if (do_gtd) {
|
||||
/* This negative delta_time marks the gap! */
|
||||
if (tot > 1) {
|
||||
@@ -1123,7 +1140,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
}
|
||||
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
|
||||
}
|
||||
|
||||
|
||||
old_nbezt += 2;
|
||||
copy_v3_v3(p3d_prev, p2);
|
||||
}
|
||||
@@ -1131,29 +1148,30 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
if (old_nbezt && do_gtd) {
|
||||
prev_bezt = nu->bezt + old_nbezt - 1;
|
||||
}
|
||||
|
||||
/* add points */
|
||||
for (i = stitch ? 1 : 0, bezt = nu->bezt + old_nbezt; i < tot; i++, pt++, bezt++) {
|
||||
float h1[3], h2[3];
|
||||
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
|
||||
|
||||
|
||||
if (i || old_nbezt) {
|
||||
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
|
||||
}
|
||||
else {
|
||||
interp_v3_v3v3(h1, p3d_cur, p3d_next, -BEZT_HANDLE_FAC);
|
||||
}
|
||||
|
||||
|
||||
if (i < tot - 1) {
|
||||
interp_v3_v3v3(h2, p3d_cur, p3d_next, BEZT_HANDLE_FAC);
|
||||
}
|
||||
else {
|
||||
interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
|
||||
}
|
||||
|
||||
|
||||
copy_v3_v3(bezt->vec[0], h1);
|
||||
copy_v3_v3(bezt->vec[1], p3d_cur);
|
||||
copy_v3_v3(bezt->vec[2], h2);
|
||||
|
||||
|
||||
/* set settings */
|
||||
bezt->h1 = bezt->h2 = HD_FREE;
|
||||
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
|
||||
@@ -1166,23 +1184,23 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
else if (bezt->weight > minmax_weights[1]) {
|
||||
minmax_weights[1] = bezt->weight;
|
||||
}
|
||||
|
||||
|
||||
/* Update timing data */
|
||||
if (do_gtd) {
|
||||
gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bezt ? len_v3v3(prev_bezt->vec[1], p3d_cur) : 0.0f);
|
||||
}
|
||||
|
||||
|
||||
/* shift coord vects */
|
||||
copy_v3_v3(p3d_prev, p3d_cur);
|
||||
copy_v3_v3(p3d_cur, p3d_next);
|
||||
|
||||
|
||||
if (i + 2 < tot) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
|
||||
}
|
||||
|
||||
|
||||
prev_bezt = bezt;
|
||||
}
|
||||
|
||||
|
||||
/* must calculate handles or else we crash */
|
||||
BKE_nurb_handles_calc(nu);
|
||||
|
||||
@@ -1200,6 +1218,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
|
||||
static void gp_stroke_finalize_curve_endpoints(Curve *cu)
|
||||
{
|
||||
/* start */
|
||||
Nurb *nu = cu->nurb.first;
|
||||
int i = 0;
|
||||
if (nu->bezt) {
|
||||
@@ -1214,7 +1233,8 @@ static void gp_stroke_finalize_curve_endpoints(Curve *cu)
|
||||
bp[i].weight = bp[i].radius = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* end */
|
||||
nu = cu->nurb.last;
|
||||
i = nu->pntsu - 1;
|
||||
if (nu->bezt) {
|
||||
@@ -1237,7 +1257,7 @@ static void gp_stroke_norm_curve_weights(Curve *cu, float minmax_weights[2])
|
||||
const float delta = minmax_weights[0];
|
||||
const float fac = 1.0f / (minmax_weights[1] - delta);
|
||||
int i;
|
||||
|
||||
|
||||
for (nu = cu->nurb.first; nu; nu = nu->next) {
|
||||
if (nu->bezt) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
@@ -1269,11 +1289,11 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
|
||||
|
||||
/* camera framing */
|
||||
rctf subrect, *subrect_ptr = NULL;
|
||||
|
||||
|
||||
/* error checking */
|
||||
if (ELEM3(NULL, gpd, gpl, gpf))
|
||||
return;
|
||||
|
||||
|
||||
/* only convert if there are any strokes on this layer's frame to convert */
|
||||
if (gpf->strokes.first == NULL)
|
||||
return;
|
||||
@@ -1282,7 +1302,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
|
||||
if (gp_camera_view_subrect(C, &subrect)) {
|
||||
subrect_ptr = &subrect;
|
||||
}
|
||||
|
||||
|
||||
/* init the curve object (remove rotation and get curve data from it)
|
||||
* - must clear transforms set on object, as those skew our results
|
||||
*/
|
||||
@@ -1291,28 +1311,34 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
|
||||
zero_v3(ob->rot);
|
||||
cu = ob->data;
|
||||
cu->flag |= CU_3D;
|
||||
|
||||
|
||||
/* rename object and curve to layer name */
|
||||
rename_id((ID *)ob, gpl->info);
|
||||
rename_id((ID *)cu, gpl->info);
|
||||
|
||||
gtd->inittime = ((bGPDstroke*)gpf->strokes.first)->inittime;
|
||||
|
||||
|
||||
gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
|
||||
|
||||
/* add points to curve */
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* Detect new strokes created because of GP_STROKE_BUFFER_MAX reached,
|
||||
* and stitch them to previous one.
|
||||
*/
|
||||
int stitch = FALSE;
|
||||
|
||||
if (prev_gps) {
|
||||
bGPDspoint *pt1 = prev_gps->points + prev_gps->totpoints - 1;
|
||||
bGPDspoint *pt2 = gps->points;
|
||||
if (pt1->x == pt2->x && pt1->y == pt2->y)
|
||||
|
||||
if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) {
|
||||
stitch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decide whether we connect this stroke to previous one */
|
||||
if (!(stitch || link_strokes))
|
||||
if (!(stitch || link_strokes)) {
|
||||
nu = NULL;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case GP_STROKECONVERT_PATH:
|
||||
gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd);
|
||||
@@ -1332,20 +1358,25 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
|
||||
gp_stroke_finalize_curve_endpoints(cu);
|
||||
|
||||
/* Update curve's weights, if needed */
|
||||
if (norm_weights && (minmax_weights[0] > 0.0f || minmax_weights[1] < 1.0f))
|
||||
if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f)))
|
||||
gp_stroke_norm_curve_weights(cu, minmax_weights);
|
||||
|
||||
/* Create the path animation, if needed */
|
||||
gp_stroke_path_animation(C, reports, cu, gtd);
|
||||
|
||||
/* Reset org object as active, else we can't edit operator's settings!!! */
|
||||
/* Reset original object as active, else we can't edit operator's settings!!! */
|
||||
/* set layers OK */
|
||||
newbase = BASACT;
|
||||
newbase->lay = base->lay;
|
||||
ob->lay = newbase->lay;
|
||||
if (base) {
|
||||
newbase->lay = base->lay;
|
||||
ob->lay = newbase->lay;
|
||||
}
|
||||
|
||||
/* restore, BKE_object_add sets active */
|
||||
BASACT = base;
|
||||
base->flag |= SELECT;
|
||||
if (base) {
|
||||
base->flag |= SELECT;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- */
|
||||
@@ -1361,13 +1392,14 @@ static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOper
|
||||
bGPDspoint *pt;
|
||||
double base_time, cur_time, prev_time = -1.0;
|
||||
int i, valid = TRUE;
|
||||
|
||||
|
||||
do {
|
||||
base_time = cur_time = gps->inittime;
|
||||
if (cur_time <= prev_time) {
|
||||
valid = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
prev_time = cur_time;
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
cur_time = base_time + (double)pt->time;
|
||||
@@ -1380,11 +1412,12 @@ static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOper
|
||||
}
|
||||
prev_time = cur_time;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
break;
|
||||
}
|
||||
} while ((gps = gps->next));
|
||||
|
||||
|
||||
if (op) {
|
||||
RNA_boolean_set(op->ptr, "use_timing_data", valid);
|
||||
}
|
||||
@@ -1396,6 +1429,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
|
||||
{
|
||||
int start_frame = RNA_int_get(ptr, "start_frame");
|
||||
int end_frame = RNA_int_get(ptr, "end_frame");
|
||||
|
||||
if (end_frame <= start_frame) {
|
||||
RNA_int_set(ptr, "end_frame", start_frame + 1);
|
||||
}
|
||||
@@ -1423,19 +1457,19 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
|
||||
int link_strokes = RNA_boolean_get(op->ptr, "use_link_strokes");
|
||||
int valid_timing;
|
||||
tGpTimingData gtd;
|
||||
|
||||
|
||||
/* check if there's data to work with */
|
||||
if (gpd == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No grease pencil data to work on");
|
||||
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
||||
if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
|
||||
BKE_report(op->reports, RPT_WARNING,
|
||||
"Current grease pencil strokes have no valid timing data, most timing options will be hidden!");
|
||||
"Current Grease Pencil strokes have no valid timing data, most timing options will be hidden!");
|
||||
}
|
||||
valid_timing = RNA_property_boolean_get(op->ptr, prop);
|
||||
|
||||
|
||||
gtd.mode = RNA_enum_get(op->ptr, "timing_mode");
|
||||
/* Check for illegal timing mode! */
|
||||
if (!valid_timing && !ELEM(gtd.mode, GP_STROKECONVERT_TIMING_NONE, GP_STROKECONVERT_TIMING_LINEAR)) {
|
||||
@@ -1445,7 +1479,8 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
|
||||
if (!link_strokes) {
|
||||
gtd.mode = GP_STROKECONVERT_TIMING_NONE;
|
||||
}
|
||||
|
||||
|
||||
/* grab all relevant settings */
|
||||
gtd.frame_range = RNA_int_get(op->ptr, "frame_range");
|
||||
gtd.start_frame = RNA_int_get(op->ptr, "start_frame");
|
||||
gtd.realtime = valid_timing ? RNA_boolean_get(op->ptr, "use_realtime") : FALSE;
|
||||
@@ -1458,13 +1493,24 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
|
||||
gtd.dists = gtd.times = NULL;
|
||||
gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
|
||||
gtd.inittime = 0.0;
|
||||
|
||||
|
||||
/* perform conversion */
|
||||
gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, >d);
|
||||
|
||||
|
||||
/* free temp memory */
|
||||
if (gtd.dists) {
|
||||
MEM_freeN(gtd.dists);
|
||||
gtd.dists = NULL;
|
||||
}
|
||||
if (gtd.times) {
|
||||
MEM_freeN(gtd.times);
|
||||
gtd.times = NULL;
|
||||
}
|
||||
|
||||
/* notifiers */
|
||||
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
|
||||
|
||||
|
||||
/* done */
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1478,7 +1524,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
|
||||
float gap_duration = RNA_float_get(ptr, "gap_duration");
|
||||
float gap_randomness = RNA_float_get(ptr, "gap_randomness");
|
||||
int valid_timing = RNA_boolean_get(ptr, "use_timing_data");
|
||||
|
||||
|
||||
/* Always show those props */
|
||||
if (strcmp(prop_id, "type") == 0 ||
|
||||
strcmp(prop_id, "use_normalize_weights") == 0 ||
|
||||
@@ -1487,7 +1533,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Never show this prop */
|
||||
if (strcmp(prop_id, "use_timing_data") == 0)
|
||||
return FALSE;
|
||||
@@ -1496,7 +1542,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
|
||||
/* Only show when link_stroke is TRUE */
|
||||
if (strcmp(prop_id, "timing_mode") == 0)
|
||||
return TRUE;
|
||||
|
||||
|
||||
if (timing_mode != GP_STROKECONVERT_TIMING_NONE) {
|
||||
/* Only show when link_stroke is TRUE and stroke timing is enabled */
|
||||
if (strcmp(prop_id, "frame_range") == 0 ||
|
||||
@@ -1504,26 +1550,26 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Only show if we have valid timing data! */
|
||||
if (valid_timing && strcmp(prop_id, "use_realtime") == 0)
|
||||
return TRUE;
|
||||
|
||||
|
||||
/* Only show if realtime or valid_timing is FALSE! */
|
||||
if ((!realtime || !valid_timing) && strcmp(prop_id, "end_frame") == 0)
|
||||
return TRUE;
|
||||
|
||||
|
||||
if (valid_timing && timing_mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
|
||||
/* Only show for custom gaps! */
|
||||
if (strcmp(prop_id, "gap_duration") == 0)
|
||||
return TRUE;
|
||||
|
||||
|
||||
/* Only show randomness for non-null custom gaps! */
|
||||
if (strcmp(prop_id, "gap_randomness") == 0 && gap_duration > 0.0f)
|
||||
if (strcmp(prop_id, "gap_randomness") == 0 && (gap_duration > 0.0f))
|
||||
return TRUE;
|
||||
|
||||
|
||||
/* Only show seed for randomize action! */
|
||||
if (strcmp(prop_id, "seed") == 0 && gap_duration > 0.0f && gap_randomness > 0.0f)
|
||||
if (strcmp(prop_id, "seed") == 0 && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1565,15 +1611,18 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
|
||||
|
||||
/* properties */
|
||||
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_normalize_weights", TRUE, "Normalize Weight",
|
||||
"Normalize weight (set from stroke width)");
|
||||
RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
|
||||
"Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
|
||||
RNA_def_boolean(ot->srna, "use_link_strokes", TRUE, "Link Strokes",
|
||||
"Whether to link strokes with zero-radius sections of curves");
|
||||
|
||||
prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
|
||||
"Timing Mode", "How to use timing data stored in strokes");
|
||||
RNA_def_enum_funcs(prop, rna_GPConvert_mode_items);
|
||||
|
||||
RNA_def_int(ot->srna, "frame_range", 100, 1, 10000, "Frame Range",
|
||||
"The duration of evaluation of the path control curve", 1, 1000);
|
||||
RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
|
||||
@@ -1583,16 +1632,18 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
|
||||
prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
|
||||
"The end frame of the path control curve (if Realtime is not set)", 1, 100000);
|
||||
RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
|
||||
|
||||
RNA_def_float(ot->srna, "gap_duration", 0.0f, 0.0f, 10000.0f, "Gap Duration",
|
||||
"Custom Gap mode: (Average) length of gaps, in frames "
|
||||
"(note: realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
|
||||
"(Note: Realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
|
||||
RNA_def_float(ot->srna, "gap_randomness", 0.0f, 0.0f, 10000.0f, "Gap Randomness",
|
||||
"Custom Gap mode: Number of frames that gap lengths can vary", 0.0f, 1000.0f);
|
||||
RNA_def_int(ot->srna, "seed", 0, 0, 1000, "Random Seed",
|
||||
"Custom Gap mode: Random generator seed", 0, 100);
|
||||
|
||||
/* Note: Internal use, this one will always be hidden by UI code... */
|
||||
prop = RNA_def_boolean(ot->srna, "use_timing_data", FALSE, "Has Valid Timing",
|
||||
"Whether the converted grease pencil layer has valid timing data (internal use)");
|
||||
"Whether the converted Grease Pencil layer has valid timing data (internal use)");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ typedef struct tGPsdata {
|
||||
|
||||
short radius; /* radius of influence for eraser */
|
||||
short flags; /* flags that can get set during runtime */
|
||||
|
||||
/* Those needs to be doubles, as (at least under unix) they are in seconds since epoch,
|
||||
|
||||
/* These need to be doubles, as (at least under unix) they are in seconds since epoch,
|
||||
* float (and its 7 digits precision) is definitively not enough here!
|
||||
* double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least.
|
||||
*/
|
||||
@@ -110,7 +110,7 @@ typedef struct tGPsdata {
|
||||
double ocurtime; /* Used when converting to path */
|
||||
|
||||
float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
|
||||
* to region space */
|
||||
* to region space */
|
||||
|
||||
float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */
|
||||
|
||||
@@ -455,11 +455,13 @@ static void gp_stroke_smooth(tGPsdata *p)
|
||||
if ((cmx <= 2) || (gpd->sbuffer == NULL))
|
||||
return;
|
||||
|
||||
/* Calculate smoothing coordinates using weighted-averages */
|
||||
/* XXX DO NOT smooth first and last points! */
|
||||
/* Calculate smoothing coordinates using weighted-averages
|
||||
* WARNING: we do NOT smooth first and last points (to avoid shrinkage)
|
||||
*/
|
||||
spt = (tGPspoint *)gpd->sbuffer;
|
||||
/* This small array stores the last two points' org coordinates, we don't want to use already averaged ones!
|
||||
* Note it is used as a cyclic buffer...
|
||||
|
||||
/* This (tmp_spt) small array stores the last two points' original coordinates,
|
||||
* as we don't want to use already averaged ones! It is used as a cyclic buffer...
|
||||
*/
|
||||
tmp_spt[0] = *spt;
|
||||
for (i = 1, spt++; i < cmx - 1; i++, spt++) {
|
||||
@@ -469,7 +471,7 @@ static void gp_stroke_smooth(tGPsdata *p)
|
||||
const tGPspoint *pd = pc + 1;
|
||||
const tGPspoint *pe = (i + 2 < cmx) ? (pc + 2) : (pd);
|
||||
|
||||
/* Store current point's org state for the two next points! */
|
||||
/* Store current point's original state for the two next points! */
|
||||
tmp_spt[i % 3] = *spt;
|
||||
|
||||
spt->x = (int)(0.1 * pa->x + 0.2 * pb->x + 0.4 * pc->x + 0.2 * pd->x + 0.1 * pe->x);
|
||||
@@ -588,7 +590,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* allocate memory for a new stroke */
|
||||
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
|
||||
|
||||
@@ -600,10 +602,10 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
|
||||
/* allocate enough memory for a continuous array for storage points */
|
||||
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
|
||||
|
||||
|
||||
/* set pointer to first non-initialized point */
|
||||
pt = gps->points + (gps->totpoints - totelem);
|
||||
|
||||
|
||||
/* copy points from the buffer to the stroke */
|
||||
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
|
||||
/* straight lines only -> only endpoints */
|
||||
@@ -722,7 +724,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
if (depth_arr)
|
||||
MEM_freeN(depth_arr);
|
||||
}
|
||||
|
||||
|
||||
/* add stroke to frame */
|
||||
BLI_addtail(&p->gpf->strokes, gps);
|
||||
gp_stroke_added_enable(p);
|
||||
@@ -735,7 +737,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||
{
|
||||
bGPDspoint *pt_tmp = gps->points;
|
||||
bGPDstroke *gsn = NULL;
|
||||
|
||||
|
||||
/* if stroke only had two points, get rid of stroke */
|
||||
if (gps->totpoints == 2) {
|
||||
/* free stroke points, then stroke */
|
||||
@@ -745,7 +747,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||
/* nothing left in stroke, so stop */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* if last segment, just remove segment from the stroke */
|
||||
else if (i == gps->totpoints - 2) {
|
||||
/* allocate new points array, and assign most of the old stroke there */
|
||||
@@ -759,17 +761,17 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||
/* nothing left in stroke, so stop */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* if first segment, just remove segment from the stroke */
|
||||
else if (i == 0) {
|
||||
/* allocate new points array, and assign most of the old stroke there */
|
||||
gps->totpoints--;
|
||||
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
|
||||
memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint) * gps->totpoints);
|
||||
|
||||
|
||||
/* We must adjust timings!
|
||||
* Each point's timing data is a delta from stroke's inittime, so as we erase the first
|
||||
* point of the stroke, we have to offset this inittime and all remaing points' delta values.
|
||||
* point of the stroke, we have to offset this inittime and all remaining points' delta values.
|
||||
* This way we get a new stroke with exactly the same timing as if user had started drawing from
|
||||
* the second point...
|
||||
*/
|
||||
@@ -777,9 +779,9 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||
bGPDspoint *pts;
|
||||
float delta = pt_tmp[1].time;
|
||||
int j;
|
||||
|
||||
gps->inittime += delta;
|
||||
|
||||
|
||||
gps->inittime += (double)delta;
|
||||
|
||||
pts = gps->points;
|
||||
for (j = 0; j < gps->totpoints; j++, pts++) {
|
||||
pts->time -= delta;
|
||||
@@ -792,7 +794,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||
/* no break here, as there might still be stuff to remove in this stroke */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* segment occurs in 'middle' of stroke, so split */
|
||||
else {
|
||||
/* duplicate stroke, and assign 'later' data to that stroke */
|
||||
@@ -814,15 +816,15 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||
bGPDspoint *pts;
|
||||
float delta = pt_tmp[i].time;
|
||||
int j;
|
||||
|
||||
gsn->inittime += delta;
|
||||
|
||||
|
||||
gsn->inittime += (double)delta;
|
||||
|
||||
pts = gsn->points;
|
||||
for (j = 0; j < gsn->totpoints; j++, pts++) {
|
||||
pts->time -= delta;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* adjust existing stroke */
|
||||
gps->totpoints = i;
|
||||
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
|
||||
@@ -844,7 +846,7 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv
|
||||
const float mval_fl[2] = {mval[0], mval[1]};
|
||||
const float screen_co_a[2] = {x0, y0};
|
||||
const float screen_co_b[2] = {x1, y1};
|
||||
|
||||
|
||||
if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
|
||||
return TRUE;
|
||||
}
|
||||
@@ -904,7 +906,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0);
|
||||
|
||||
/* do boundbox check first */
|
||||
|
||||
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
|
||||
/* only check if point is inside */
|
||||
if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) {
|
||||
@@ -922,10 +923,10 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
/* get points to work with */
|
||||
pt1 = gps->points + i;
|
||||
pt2 = gps->points + i + 1;
|
||||
|
||||
|
||||
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0);
|
||||
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1);
|
||||
|
||||
|
||||
/* check that point segment of the boundbox of the eraser stroke */
|
||||
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
|
||||
((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
|
||||
@@ -1033,7 +1034,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SPACE_NODE:
|
||||
{
|
||||
/* SpaceNode *snode = curarea->spacedata.first; */
|
||||
@@ -1554,14 +1555,14 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
|
||||
PointerRNA itemptr;
|
||||
float mousef[2];
|
||||
int tablet = 0;
|
||||
|
||||
|
||||
/* convert from window-space to area-space mouse coordinates
|
||||
* NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
|
||||
*/
|
||||
p->mval[0] = event->mval[0] + 1;
|
||||
p->mval[1] = event->mval[1] + 1;
|
||||
p->curtime = PIL_check_seconds_timer();
|
||||
|
||||
|
||||
/* handle pressure sensitivity (which is supplied by tablets) */
|
||||
if (event->custom == EVT_DATA_TABLET) {
|
||||
wmTabletData *wmtab = event->customdata;
|
||||
@@ -1592,7 +1593,7 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
|
||||
p->mvalo[1] = p->mval[1];
|
||||
p->opressure = p->pressure;
|
||||
p->inittime = p->ocurtime = p->curtime;
|
||||
|
||||
|
||||
/* special exception here for too high pressure values on first touch in
|
||||
* windows for some tablets, then we just skip first touch...
|
||||
*/
|
||||
@@ -1601,7 +1602,7 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
|
||||
}
|
||||
|
||||
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
|
||||
|
||||
|
||||
/* apply the current latest drawing point */
|
||||
gpencil_draw_apply(op, p);
|
||||
|
||||
@@ -1754,7 +1755,7 @@ static int gpencil_area_exists(bContext *C, ScrArea *sa_test)
|
||||
static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
|
||||
{
|
||||
tGPsdata *p = op->customdata;
|
||||
|
||||
|
||||
/* we must check that we're still within the area that we're set up to work from
|
||||
* otherwise we could crash (see bug #20586)
|
||||
*/
|
||||
@@ -1762,20 +1763,20 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
|
||||
printf("\t\t\tGP - wrong area execution abort!\n");
|
||||
p->status = GP_STATUS_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* printf("\t\tGP - start stroke\n"); */
|
||||
|
||||
|
||||
/* we may need to set up paint env again if we're resuming */
|
||||
/* XXX: watch it with the paintmode! in future,
|
||||
* it'd be nice to allow changing paint-mode when in sketching-sessions */
|
||||
/* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */
|
||||
|
||||
|
||||
if (gp_session_initdata(C, p))
|
||||
gp_paint_initstroke(p, p->paintmode);
|
||||
|
||||
|
||||
if (p->status != GP_STATUS_ERROR)
|
||||
p->status = GP_STATUS_PAINTING;
|
||||
|
||||
|
||||
return op->customdata;
|
||||
}
|
||||
|
||||
@@ -1800,7 +1801,7 @@ static void gpencil_stroke_end(wmOperator *op)
|
||||
static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
tGPsdata *p = op->customdata;
|
||||
int estate = OPERATOR_PASS_THROUGH; /* default exit state */
|
||||
int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
|
||||
|
||||
/* if (event->type == NDOF_MOTION)
|
||||
* return OPERATOR_PASS_THROUGH;
|
||||
@@ -1814,7 +1815,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
* better in tools that immediately apply
|
||||
* in 3D space.
|
||||
*/
|
||||
|
||||
|
||||
/* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
|
||||
if (ISKEYBOARD(event->type))
|
||||
estate = OPERATOR_RUNNING_MODAL;
|
||||
|
||||
@@ -153,6 +153,11 @@ int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short
|
||||
void EDBM_selectmode_set(struct BMEditMesh *em);
|
||||
void EDBM_selectmode_convert(struct BMEditMesh *em, const short selectmode_old, const short selectmode_new);
|
||||
|
||||
/* user access this */
|
||||
int EDBM_selectmode_toggle(struct bContext *C, const short selectmode_new,
|
||||
const int action, const int use_extend, const int use_expand);
|
||||
|
||||
|
||||
void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
|
||||
|
||||
void EDBM_select_toggle_all(struct BMEditMesh *em);
|
||||
|
||||
@@ -358,7 +358,7 @@ struct uiBlock {
|
||||
|
||||
char color_profile; /* color profile for correcting linear colors for display */
|
||||
|
||||
char *display_device; /* display devide name used to display this block,
|
||||
char *display_device; /* display device name used to display this block,
|
||||
* used by color widgets to transform colors from/to scene linear
|
||||
*/
|
||||
};
|
||||
|
||||
@@ -68,6 +68,8 @@
|
||||
#define EM_SEPR_X 6
|
||||
#define EM_SEPR_Y 6
|
||||
|
||||
// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
|
||||
|
||||
#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
|
||||
if (ot == NULL) { \
|
||||
ui_item_disabled(layout, _opname); \
|
||||
@@ -2840,10 +2842,12 @@ const char *uiLayoutIntrospect(uiLayout *layout)
|
||||
return str;
|
||||
}
|
||||
|
||||
#ifdef USE_OP_RESET_BUT
|
||||
static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, void *UNUSED(arg_dummy2))
|
||||
{
|
||||
WM_operator_properties_reset((wmOperator *)op_pt);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* this function does not initialize the layout, functions can be called on the layout before and after */
|
||||
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
|
||||
@@ -2911,6 +2915,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OP_RESET_BUT
|
||||
/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
|
||||
* but this is not so important if this button is drawn in those cases
|
||||
* (which isn't all that likely anyway) - campbell */
|
||||
@@ -2925,6 +2930,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
|
||||
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
|
||||
uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set various special settings for buttons */
|
||||
{
|
||||
|
||||
@@ -867,7 +867,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
|
||||
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
|
||||
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
|
||||
|
||||
if (modifier_sameTopology(md) && !modifier_nonGeometrical(md))
|
||||
if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md))
|
||||
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0, "apply_as", MODIFIER_APPLY_SHAPE);
|
||||
}
|
||||
|
||||
|
||||
@@ -420,7 +420,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
|
||||
if (!view_aligned)
|
||||
rot[0] += (float)M_PI / 2.0f;
|
||||
|
||||
obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
|
||||
obedit = make_prim_init(C, "Suzanne", &dia, mat, &state, loc, rot, layer);
|
||||
mat[0][0] *= dia;
|
||||
mat[1][1] *= dia;
|
||||
mat[2][2] *= dia;
|
||||
|
||||
@@ -157,13 +157,13 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
|
||||
|
||||
|
||||
if (flag & BMBVH_RESPECT_SELECT) {
|
||||
/* note, the arrays wont allign now! take care */
|
||||
/* note, the arrays wont align now! take care */
|
||||
if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (flag & BMBVH_RESPECT_HIDDEN) {
|
||||
/* note, the arrays wont allign now! take care */
|
||||
/* note, the arrays wont align now! take care */
|
||||
if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2573,8 +2573,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
|
||||
int nco = BLI_countlist(chain) - 1;
|
||||
float (*cos)[3] = NULL;
|
||||
KnifeVert **kverts;
|
||||
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, nco, __func__);
|
||||
BLI_array_fixedstack_declare(kverts, BM_NGON_STACK_SIZE, nco, __func__);
|
||||
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
|
||||
BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
|
||||
|
||||
kfe = ((Ref *)chain->first)->ref;
|
||||
v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v;
|
||||
|
||||
@@ -307,7 +307,8 @@ static void ringsel_find_edge(RingSelOpData *lcd, int cuts)
|
||||
static void ringsel_finish(bContext *C, wmOperator *op)
|
||||
{
|
||||
RingSelOpData *lcd = op->customdata;
|
||||
int cuts = RNA_int_get(op->ptr, "number_cuts");
|
||||
const int cuts = RNA_int_get(op->ptr, "number_cuts");
|
||||
const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness");
|
||||
|
||||
if (lcd->eed) {
|
||||
BMEditMesh *em = lcd->em;
|
||||
@@ -319,7 +320,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
|
||||
* Note though that it will break edgeslide in this specific case.
|
||||
* See [#31939]. */
|
||||
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
smoothness, 0.0f, 0.0f,
|
||||
cuts,
|
||||
SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, 0);
|
||||
|
||||
@@ -413,6 +414,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op)
|
||||
|
||||
static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
RingSelOpData *lcd;
|
||||
BMEdge *edge;
|
||||
@@ -438,13 +440,17 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
|
||||
lcd->eed = edge;
|
||||
ringsel_find_edge(lcd, 1);
|
||||
}
|
||||
ED_area_headerprint(CTX_wm_area(C), "Select a ring to be cut, use mouse-wheel or page-up/down for number of cuts");
|
||||
ED_area_headerprint(sa,
|
||||
"Select a ring to be cut, "
|
||||
"use mouse-wheel or page-up/down for number of cuts, "
|
||||
"Hold Alt for smooth");
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
float smoothness = RNA_float_get(op->ptr, "smoothness");
|
||||
int cuts = RNA_int_get(op->ptr, "number_cuts");
|
||||
RingSelOpData *lcd = op->customdata;
|
||||
int show_cuts = 0;
|
||||
@@ -491,11 +497,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
case WHEELUPMOUSE: /* change number of cuts */
|
||||
if (event->val == KM_RELEASE)
|
||||
break;
|
||||
|
||||
cuts++;
|
||||
RNA_int_set(op->ptr, "number_cuts", cuts);
|
||||
ringsel_find_edge(lcd, cuts);
|
||||
show_cuts = TRUE;
|
||||
if (event->alt == 0) {
|
||||
cuts++;
|
||||
RNA_int_set(op->ptr, "number_cuts", cuts);
|
||||
ringsel_find_edge(lcd, cuts);
|
||||
show_cuts = TRUE;
|
||||
}
|
||||
else {
|
||||
smoothness = min_ff(smoothness + 0.05f, 4.0f);
|
||||
RNA_float_set(op->ptr, "smoothness", smoothness);
|
||||
show_cuts = TRUE;
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(lcd->ar);
|
||||
break;
|
||||
@@ -505,10 +517,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
if (event->val == KM_RELEASE)
|
||||
break;
|
||||
|
||||
cuts = max_ii(cuts - 1, 0);
|
||||
RNA_int_set(op->ptr, "number_cuts", cuts);
|
||||
ringsel_find_edge(lcd, cuts);
|
||||
show_cuts = TRUE;
|
||||
if (event->alt == 0) {
|
||||
cuts = max_ii(cuts - 1, 0);
|
||||
RNA_int_set(op->ptr, "number_cuts", cuts);
|
||||
ringsel_find_edge(lcd, cuts);
|
||||
show_cuts = TRUE;
|
||||
}
|
||||
else {
|
||||
smoothness = max_ff(smoothness - 0.05f, 0.0f);
|
||||
RNA_float_set(op->ptr, "smoothness", smoothness);
|
||||
show_cuts = TRUE;
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(lcd->ar);
|
||||
break;
|
||||
@@ -552,7 +571,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
if (show_cuts) {
|
||||
char buf[64];
|
||||
BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d", cuts);
|
||||
BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d, Smooth: %.2f (Alt)", cuts, smoothness);
|
||||
ED_area_headerprint(CTX_wm_area(C), buf);
|
||||
}
|
||||
|
||||
@@ -604,4 +623,7 @@ void MESH_OT_loopcut(wmOperatorType *ot)
|
||||
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
|
||||
/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor", 0.0f, 4.0f);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_util.h"
|
||||
#include "ED_uvedit.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_view3d.h"
|
||||
@@ -68,6 +69,7 @@
|
||||
|
||||
#include "mesh_intern.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
/* ****************************** MIRROR **************** */
|
||||
|
||||
@@ -917,6 +919,74 @@ void MESH_OT_select_similar(wmOperatorType *ot)
|
||||
RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
/* **************** Mode Select *************** */
|
||||
|
||||
static int edbm_select_mode_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
const int action = RNA_enum_get(op->ptr, "action");
|
||||
const int use_extend = RNA_boolean_get(op->ptr, "use_extend");
|
||||
const int use_expand = RNA_boolean_get(op->ptr, "use_expand");
|
||||
|
||||
if (EDBM_selectmode_toggle(C, type, action, use_extend, use_expand)) {
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
// RNA_enum_set(op->ptr, "type"); /* type must be set already */
|
||||
RNA_boolean_set(op->ptr, "use_extend", event->shift);
|
||||
RNA_boolean_set(op->ptr, "use_expand", event->ctrl);
|
||||
return edbm_select_mode_exec(C, op);
|
||||
}
|
||||
|
||||
void MESH_OT_select_mode(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem elem_items[] = {
|
||||
{SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""},
|
||||
{SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edges", ""},
|
||||
{SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Faces", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static EnumPropertyItem actions_items[] = {
|
||||
{0, "DISABLE", 0, "Disable", "Disable selected markers"},
|
||||
{1, "ENABLE", 0, "Enable", "Enable selected markers"},
|
||||
{2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Select Mode";
|
||||
ot->idname = "MESH_OT_select_mode";
|
||||
ot->description = "Change selection mode";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = edbm_select_mode_invoke;
|
||||
ot->exec = edbm_select_mode_exec;
|
||||
ot->poll = ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop = RNA_def_boolean(ot->srna, "use_extend", FALSE, "Extend", "");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
prop = RNA_def_boolean(ot->srna, "use_expand", FALSE, "Expand", "");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
ot->prop = prop = RNA_def_enum(ot->srna, "type", elem_items, 0, "Type", "");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
|
||||
}
|
||||
|
||||
/* ***************************************************** */
|
||||
|
||||
/* **************** LOOP SELECTS *************** */
|
||||
@@ -1891,56 +1961,146 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s
|
||||
BMFace *efa;
|
||||
BMIter iter;
|
||||
|
||||
/* first tag-to-select, then select --- this avoids a feedback loop */
|
||||
|
||||
/* have to find out what the selectionmode was previously */
|
||||
if (selectmode_old == SCE_SELECT_VERTEX) {
|
||||
if (selectmode_new == SCE_SELECT_EDGE) {
|
||||
/* select all edges associated with every selected vertex */
|
||||
eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
|
||||
for (; eed; eed = BM_iter_step(&iter)) {
|
||||
if ((BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
|
||||
BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))
|
||||
{
|
||||
/* select all edges associated with every selected vert */
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
|
||||
BM_edge_select_set(em->bm, eed, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (selectmode_new == SCE_SELECT_FACE) {
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
/* select all faces associated with every selected vert */
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_vert_flag_test(efa, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
/* select all faces associated with every selected vertex */
|
||||
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
|
||||
for (; efa; efa = BM_iter_step(&iter)) {
|
||||
l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
|
||||
for (; l; l = BM_iter_step(&liter)) {
|
||||
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
|
||||
BM_face_select_set(em->bm, efa, TRUE);
|
||||
break;
|
||||
}
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
|
||||
BM_face_select_set(em->bm, efa, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (selectmode_old == SCE_SELECT_EDGE) {
|
||||
if (selectmode_new == SCE_SELECT_FACE) {
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
/* select all faces associated with every selected edge */
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
/* select all faces associated with every selected vertex */
|
||||
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
|
||||
for (; efa; efa = BM_iter_step(&iter)) {
|
||||
l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
|
||||
for (; l; l = BM_iter_step(&liter)) {
|
||||
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
|
||||
BM_face_select_set(em->bm, efa, TRUE);
|
||||
break;
|
||||
}
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
|
||||
BM_face_select_set(em->bm, efa, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* user facing function, does notification and undo push */
|
||||
int EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
|
||||
const int action, const int use_extend, const int use_expand)
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = NULL;
|
||||
int ret = FALSE;
|
||||
|
||||
if (obedit && obedit->type == OB_MESH) {
|
||||
em = BMEdit_FromObject(obedit);
|
||||
}
|
||||
|
||||
if (em == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case -1:
|
||||
/* already set */
|
||||
break;
|
||||
case 0: /* disable */
|
||||
/* check we have something to do */
|
||||
if ((em->selectmode & selectmode_new) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
em->selectmode &= ~selectmode_new;
|
||||
break;
|
||||
case 1: /* enable */
|
||||
/* check we have something to do */
|
||||
if ((em->selectmode & selectmode_new) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
em->selectmode |= selectmode_new;
|
||||
break;
|
||||
case 2: /* toggle */
|
||||
/* can't disable this flag if its the only one set */
|
||||
if (em->selectmode == selectmode_new) {
|
||||
return FALSE;
|
||||
}
|
||||
em->selectmode ^= selectmode_new;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
|
||||
switch (selectmode_new) {
|
||||
case SCE_SELECT_VERTEX:
|
||||
if (use_extend == 0 || em->selectmode == 0)
|
||||
em->selectmode = SCE_SELECT_VERTEX;
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
ret = TRUE;
|
||||
break;
|
||||
case SCE_SELECT_EDGE:
|
||||
if (use_extend == 0 || em->selectmode == 0) {
|
||||
if (use_expand) {
|
||||
const short selmode_max = highest_order_bit_s(ts->selectmode);
|
||||
if (selmode_max == SCE_SELECT_VERTEX) {
|
||||
EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
|
||||
}
|
||||
}
|
||||
em->selectmode = SCE_SELECT_EDGE;
|
||||
}
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
ret = TRUE;
|
||||
break;
|
||||
case SCE_SELECT_FACE:
|
||||
if (use_extend == 0 || em->selectmode == 0) {
|
||||
if (use_expand) {
|
||||
const short selmode_max = highest_order_bit_s(ts->selectmode);
|
||||
if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
|
||||
EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
|
||||
}
|
||||
}
|
||||
|
||||
em->selectmode = SCE_SELECT_FACE;
|
||||
}
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == TRUE) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select)
|
||||
{
|
||||
|
||||
@@ -129,6 +129,7 @@ void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot);
|
||||
void MESH_OT_edges_select_sharp(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_similar(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_mode(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_random(struct wmOperatorType *ot);
|
||||
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
|
||||
void MESH_OT_mark_seam(struct wmOperatorType *ot);
|
||||
|
||||
@@ -130,6 +130,7 @@ void ED_operatortypes_mesh(void)
|
||||
WM_operatortype_append(MESH_OT_edge_face_add);
|
||||
WM_operatortype_append(MESH_OT_select_shortest_path);
|
||||
WM_operatortype_append(MESH_OT_select_similar);
|
||||
WM_operatortype_append(MESH_OT_select_mode);
|
||||
WM_operatortype_append(MESH_OT_loop_multi_select);
|
||||
WM_operatortype_append(MESH_OT_mark_seam);
|
||||
WM_operatortype_append(MESH_OT_mark_sharp);
|
||||
|
||||
@@ -555,7 +555,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M
|
||||
Key *key = me->key;
|
||||
KeyBlock *kb;
|
||||
|
||||
if (!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
|
||||
if (!modifier_isSameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
|
||||
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
|
||||
return 0;
|
||||
}
|
||||
@@ -688,6 +688,13 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
|
||||
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
|
||||
return 0;
|
||||
}
|
||||
else if ((ob->mode & OB_MODE_SCULPT) &&
|
||||
(find_multires_modifier_before(scene, md)) &&
|
||||
(modifier_isSameTopology(md) == FALSE))
|
||||
{
|
||||
BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (md != ob->modifiers.first)
|
||||
BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
|
||||
@@ -1000,7 +1007,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
|
||||
Object *ob = ED_object_active_context(C);
|
||||
ModifierData *md = edit_modifier_property_get(op, ob, 0);
|
||||
int apply_as = RNA_enum_get(op->ptr, "apply_as");
|
||||
|
||||
|
||||
if (!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -1225,7 +1225,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
|
||||
return lay;
|
||||
}
|
||||
|
||||
static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
if (v3d && v3d->localvd) {
|
||||
@@ -1233,7 +1233,7 @@ static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
}
|
||||
else {
|
||||
move_to_layer_init(C, op);
|
||||
return WM_operator_props_popup(C, op, event);
|
||||
return WM_operator_props_dialog_popup(C, op, 260, 30);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -845,25 +845,26 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
|
||||
static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
|
||||
{
|
||||
MDeformVert *dv = NULL;
|
||||
BMVert *eve;
|
||||
Mesh *me;
|
||||
|
||||
/* get the deform vertices corresponding to the vertnum */
|
||||
if (ob->type == OB_MESH) {
|
||||
me = ob->data;
|
||||
Mesh *me = ob->data;
|
||||
|
||||
if (me->edit_btmesh) {
|
||||
eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
|
||||
/* warning, this lookup is _not_ fast */
|
||||
BMVert *eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
|
||||
if (!eve) {
|
||||
return 0.0f;
|
||||
}
|
||||
dv = CustomData_bmesh_get(&me->edit_btmesh->bm->vdata, eve->head.data, CD_MDEFORMVERT);
|
||||
}
|
||||
else {
|
||||
if (vertnum >= me->totvert) {
|
||||
return 0.0f;
|
||||
if (me->dvert) {
|
||||
if (vertnum >= me->totvert) {
|
||||
return 0.0f;
|
||||
}
|
||||
dv = &me->dvert[vertnum];
|
||||
}
|
||||
dv = &me->dvert[vertnum];
|
||||
}
|
||||
}
|
||||
else if (ob->type == OB_LATTICE) {
|
||||
|
||||
@@ -248,7 +248,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
|
||||
|
||||
void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
|
||||
{
|
||||
/* gatheravailable texture users in context. runs on every draw of
|
||||
/* gather available texture users in context. runs on every draw of
|
||||
* properties editor, before the buttons are created. */
|
||||
ButsContextTexture *ct = sbuts->texuser;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
@@ -1497,7 +1497,7 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
|
||||
|
||||
if (onlyv2d) {
|
||||
/* if manual calibration is used then grease pencil data is already
|
||||
* drawed in draw_distortion */
|
||||
* drawn in draw_distortion */
|
||||
if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) {
|
||||
glPushMatrix();
|
||||
glMultMatrixf(sc->unistabmat);
|
||||
|
||||
@@ -1686,7 +1686,7 @@ static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
if (ar->regiontype == RGN_TYPE_WINDOW) {
|
||||
/* bounding box of 30 pixels is used for markers shortcuts,
|
||||
* prevent conflict with markers shortcurts here
|
||||
* prevent conflict with markers shortcuts here
|
||||
*/
|
||||
if (event->mval[1] <= 30)
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
@@ -945,7 +945,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_GPENCIL:
|
||||
if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
|
||||
if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -310,21 +310,14 @@ static char *view3d_modeselect_pup(Scene *scene)
|
||||
return (string);
|
||||
}
|
||||
|
||||
|
||||
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
View3D *v3d = sa->spacedata.first;
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = NULL;
|
||||
int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
|
||||
const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
|
||||
PointerRNA props_ptr;
|
||||
|
||||
if (obedit && obedit->type == OB_MESH) {
|
||||
em = BMEdit_FromObject(obedit);
|
||||
}
|
||||
|
||||
/* watch it: if sa->win does not exist, check that when calling direct drawing routines */
|
||||
|
||||
switch (event) {
|
||||
@@ -336,42 +329,17 @@ static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
|
||||
break;
|
||||
|
||||
case B_SEL_VERT:
|
||||
if (em) {
|
||||
if (shift == 0 || em->selectmode == 0)
|
||||
em->selectmode = SCE_SELECT_VERTEX;
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Vertex");
|
||||
}
|
||||
break;
|
||||
case B_SEL_EDGE:
|
||||
if (em) {
|
||||
if (shift == 0 || em->selectmode == 0) {
|
||||
if ((em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX) {
|
||||
if (ctrl) EDBM_selectmode_convert(em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
|
||||
}
|
||||
em->selectmode = SCE_SELECT_EDGE;
|
||||
}
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Edge");
|
||||
}
|
||||
break;
|
||||
case B_SEL_FACE:
|
||||
if (em) {
|
||||
if (shift == 0 || em->selectmode == 0) {
|
||||
if (((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) ||
|
||||
((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE))
|
||||
{
|
||||
if (ctrl) EDBM_selectmode_convert(em, (ts->selectmode ^ SCE_SELECT_FACE), SCE_SELECT_FACE);
|
||||
}
|
||||
em->selectmode = SCE_SELECT_FACE;
|
||||
}
|
||||
ts->selectmode = em->selectmode;
|
||||
EDBM_selectmode_set(em);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
|
||||
ED_undo_push(C, "Selectmode Set: Face");
|
||||
}
|
||||
break;
|
||||
@@ -430,9 +398,15 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
|
||||
|
||||
row = uiLayoutRow(layout, TRUE);
|
||||
block = uiLayoutGetBlock(row);
|
||||
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select - Shift-Click for multiple modes");
|
||||
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select - Shift-Click for multiple modes");
|
||||
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select - Shift-Click for multiple modes");
|
||||
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
|
||||
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
|
||||
"Vertex select - Shift-Click for multiple modes");
|
||||
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
|
||||
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
|
||||
"Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection");
|
||||
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
|
||||
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
|
||||
"Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1553,7 +1553,112 @@ static void UV_OT_align(wmOperatorType *ot)
|
||||
/* properties */
|
||||
RNA_def_enum(ot->srna, "axis", axis_items, 'a', "Axis", "Axis to align UV locations on");
|
||||
}
|
||||
/* ******************** weld near operator **************** */
|
||||
|
||||
typedef struct UVvert {
|
||||
MLoopUV *uv_loop;
|
||||
int weld;
|
||||
} UVvert;
|
||||
|
||||
static int remove_doubles_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceImage *sima;
|
||||
Scene *scene;
|
||||
Object *obedit;
|
||||
Image *ima;
|
||||
BMEditMesh *em;
|
||||
MTexPoly *tf;
|
||||
int UV_a;
|
||||
int UV_b;
|
||||
float UVp1[2];
|
||||
float UVp2[2];
|
||||
float weld_dist;
|
||||
MLoopUV **loop_arr = NULL;
|
||||
BLI_array_declare(loop_arr);
|
||||
|
||||
UVvert *vert_arr = NULL;
|
||||
BLI_array_declare(vert_arr);
|
||||
BMIter iter, liter;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
|
||||
sima = CTX_wm_space_image(C);
|
||||
scene = CTX_data_scene(C);
|
||||
obedit = CTX_data_edit_object(C);
|
||||
em = BMEdit_FromObject(obedit);
|
||||
ima = CTX_data_edit_image(C);
|
||||
|
||||
weld_dist = RNA_float_get(op->ptr, "weld_dist");
|
||||
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
|
||||
if (!uvedit_face_visible_test(scene, ima, efa, tf))
|
||||
continue;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(em, scene, l)) {
|
||||
MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
|
||||
UVvert vert;
|
||||
vert.uv_loop = luv;
|
||||
vert.weld = FALSE;
|
||||
BLI_array_append(vert_arr, vert);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (UV_a = 0; UV_a<BLI_array_count(vert_arr); UV_a++){
|
||||
if (vert_arr[UV_a].weld == FALSE){
|
||||
float far_UV [2];
|
||||
float near_UV [2];
|
||||
|
||||
BLI_array_empty(loop_arr);
|
||||
BLI_array_append(loop_arr, vert_arr[UV_a].uv_loop);
|
||||
|
||||
copy_v2_v2(UVp1, vert_arr[UV_a].uv_loop->uv);
|
||||
|
||||
copy_v2_v2(near_UV, UVp1);
|
||||
copy_v2_v2(far_UV, UVp1);
|
||||
|
||||
vert_arr[UV_a].weld = TRUE;
|
||||
for (UV_b = 0; UV_b<BLI_array_count(vert_arr); UV_b++){
|
||||
copy_v2_v2(UVp2, vert_arr[UV_b].uv_loop->uv);
|
||||
if (UV_b != UV_a && vert_arr[UV_b].weld == FALSE && UVp1[0]-UVp2[0] > -weld_dist && UVp1[0] - UVp2[0] < weld_dist && UVp1[1] - UVp2[1] > -weld_dist && UVp1[1] - UVp2[1] < weld_dist){
|
||||
minmax_v2v2_v2(near_UV, far_UV, UVp2);
|
||||
BLI_array_append(loop_arr, vert_arr[UV_b].uv_loop);
|
||||
vert_arr[UV_b].weld = TRUE;
|
||||
}
|
||||
}
|
||||
for (UV_b = 0; UV_b<BLI_array_count(loop_arr); UV_b++){
|
||||
mid_v2_v2v2(loop_arr[UV_b]->uv, far_UV, near_UV);
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_array_free(loop_arr);
|
||||
BLI_array_free(vert_arr);
|
||||
|
||||
uvedit_live_unwrap_update(sima, scene, obedit);
|
||||
DAG_id_tag_update(obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UV_OT_remove_doubles(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Remove Doubles";
|
||||
ot->description = "Selected UV vertices that are within a radius of eachother are welded together";
|
||||
ot->idname = "UV_OT_remove_doubles";
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = remove_doubles_exec;
|
||||
ot->poll = ED_operator_uvedit;
|
||||
|
||||
RNA_def_float(ot->srna, "weld_dist", 0.02f, 0.0f, 1.0f, "Weld Distance", "Maximum distance between welded vertices", 0.001f, 10.0f);
|
||||
}
|
||||
/* ******************** weld operator **************** */
|
||||
|
||||
static int weld_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
@@ -3776,6 +3881,7 @@ void ED_operatortypes_uvedit(void)
|
||||
WM_operatortype_append(UV_OT_seams_from_islands);
|
||||
WM_operatortype_append(UV_OT_mark_seam);
|
||||
WM_operatortype_append(UV_OT_weld);
|
||||
WM_operatortype_append(UV_OT_remove_doubles);
|
||||
WM_operatortype_append(UV_OT_pin);
|
||||
|
||||
WM_operatortype_append(UV_OT_average_islands_scale);
|
||||
|
||||
@@ -1444,18 +1444,22 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
}
|
||||
case PADENTER:
|
||||
case RETKEY:
|
||||
if (stitch_process_data(stitch_state, scene, 1)) {
|
||||
stitch_exit(C, op, 1);
|
||||
return OPERATOR_FINISHED;
|
||||
if (event->val == KM_PRESS) {
|
||||
if (stitch_process_data(stitch_state, scene, 1)) {
|
||||
stitch_exit(C, op, 1);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
return stitch_cancel(C, op);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return stitch_cancel(C, op);
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
/* Increase limit */
|
||||
case PADPLUSKEY:
|
||||
case WHEELUPMOUSE:
|
||||
if (event->alt) {
|
||||
if (event->val == KM_PRESS && event->alt) {
|
||||
stitch_state->limit_dist += 0.01f;
|
||||
if (!stitch_process_data(stitch_state, scene, 0)) {
|
||||
return stitch_cancel(C, op);
|
||||
@@ -1468,7 +1472,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
/* Decrease limit */
|
||||
case PADMINUS:
|
||||
case WHEELDOWNMOUSE:
|
||||
if (event->alt) {
|
||||
if (event->val == KM_PRESS && event->alt) {
|
||||
stitch_state->limit_dist -= 0.01f;
|
||||
stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
|
||||
if (!stitch_process_data(stitch_state, scene, 0)) {
|
||||
|
||||
@@ -1414,7 +1414,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
|
||||
BMIter liter;
|
||||
MLoopUV *luv;
|
||||
float **uvs = NULL;
|
||||
BLI_array_fixedstack_declare(uvs, BM_NGON_STACK_SIZE, efa->len, __func__);
|
||||
BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__);
|
||||
float dx;
|
||||
int i, mi;
|
||||
|
||||
|
||||
@@ -79,12 +79,14 @@ static IKPlugin ikplugin_tab[] = {
|
||||
itasc_update_param,
|
||||
itasc_test_constraint,
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static IKPlugin *get_plugin(bPose *pose)
|
||||
{
|
||||
if (!pose || pose->iksolver < 0 || pose->iksolver >= (sizeof(ikplugin_tab) / sizeof(IKPlugin)))
|
||||
if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab)/sizeof(IKPlugin) - 2))
|
||||
return NULL;
|
||||
|
||||
return &ikplugin_tab[pose->iksolver];
|
||||
|
||||
@@ -164,7 +164,7 @@ typedef struct ColormanageProcessor {
|
||||
* but they holds indexes of all transformations and color spaces, not
|
||||
* their names.
|
||||
*
|
||||
* This helps avoid extra colorsmace / display / view lookup without
|
||||
* This helps avoid extra colorspace / display / view lookup without
|
||||
* requiring to pass all variables which affects on display buffer
|
||||
* to color management cache system and keeps calls small and nice.
|
||||
*/
|
||||
|
||||
@@ -387,8 +387,8 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
|
||||
/*
|
||||
* 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space
|
||||
*
|
||||
* - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the imager is used
|
||||
* - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the imager is used
|
||||
* - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the image is used
|
||||
* - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the image is used
|
||||
*/
|
||||
|
||||
/* ****************************** COPIED FROM image_to_j2k.c */
|
||||
|
||||
@@ -348,25 +348,12 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
|
||||
g = *buffer++;
|
||||
b = *buffer++;
|
||||
k = *buffer++;
|
||||
|
||||
k = 255 - k;
|
||||
r -= k;
|
||||
if (r & 0xffffff00) {
|
||||
if (r < 0) r = 0;
|
||||
else r = 255;
|
||||
}
|
||||
g -= k;
|
||||
if (g & 0xffffff00) {
|
||||
if (g < 0) g = 0;
|
||||
else g = 255;
|
||||
}
|
||||
b -= k;
|
||||
if (b & 0xffffff00) {
|
||||
if (b < 0) b = 0;
|
||||
else b = 255;
|
||||
}
|
||||
|
||||
rect[3] = 255 - k;
|
||||
|
||||
r = (r * k) / 255;
|
||||
g = (g * k) / 255;
|
||||
b = (b * k) / 255;
|
||||
|
||||
rect[3] = 255;
|
||||
rect[2] = b;
|
||||
rect[1] = g;
|
||||
rect[0] = r;
|
||||
|
||||
@@ -881,7 +881,7 @@ void IMB_exr_close(void *handle)
|
||||
/* get a substring from the end of the name, separated by '.' */
|
||||
static int imb_exr_split_token(const char *str, const char *end, const char **token)
|
||||
{
|
||||
int maxlen = end - str;
|
||||
ptrdiff_t maxlen = end - str;
|
||||
int len = 0;
|
||||
while (len < maxlen && *(end - len - 1) != '.') {
|
||||
len++;
|
||||
@@ -1183,7 +1183,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
|
||||
frameBuffer.insert(exr_rgba_channelname(file, "B"),
|
||||
Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride));
|
||||
|
||||
/* 1.0 is fill value, this still neesd to be assigned even when (is_alpha == 0) */
|
||||
/* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
|
||||
frameBuffer.insert(exr_rgba_channelname(file, "A"),
|
||||
Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f));
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
|
||||
/* experiment with more advanced exr api */
|
||||
|
||||
/* Note: as for now openexr only supports 32 chars in channel names.
|
||||
* This api also supports max 8 channels per pass now. easy to fix! */
|
||||
#define EXR_LAY_MAXNAME 51
|
||||
#define EXR_PASS_MAXNAME 11
|
||||
/* XXX layer+pass name max 64? */
|
||||
/* This api also supports max 8 channels per pass now. easy to fix! */
|
||||
#define EXR_LAY_MAXNAME 64
|
||||
#define EXR_PASS_MAXNAME 64
|
||||
#define EXR_TOT_MAXNAME 64
|
||||
#define EXR_PASS_MAXCHAN 8
|
||||
|
||||
|
||||
@@ -50,12 +50,13 @@ typedef struct bGPDspoint {
|
||||
*/
|
||||
typedef struct bGPDstroke {
|
||||
struct bGPDstroke *next, *prev;
|
||||
|
||||
bGPDspoint *points; /* array of data-points for stroke */
|
||||
void *pad; /* keep 4 pointers at the beginning, padding for 'inittime' is tricky 64/32bit */
|
||||
int totpoints; /* number of data-points in array */
|
||||
|
||||
short thickness; /* thickness of stroke (currently not used) */
|
||||
short flag; /* various settings about this stroke */
|
||||
|
||||
double inittime; /* Init time of stroke */
|
||||
} bGPDstroke;
|
||||
|
||||
|
||||
@@ -1201,7 +1201,7 @@ typedef struct Scene {
|
||||
#define R_NO_OVERWRITE 0x400000 /* skip existing files */
|
||||
#define R_TOUCH 0x800000 /* touch files before rendering */
|
||||
#define R_SIMPLIFY 0x1000000
|
||||
#define R_EDGE_FRS 0x2000000 /* R_EDGE for Freestyle */
|
||||
#define R_EDGE_FRS 0x2000000 /* R_EDGE reserved for Freestyle */
|
||||
#define R_PERSISTENT_DATA 0x4000000 /* keep data around for re-render */
|
||||
|
||||
/* seq_flag */
|
||||
|
||||
@@ -163,7 +163,7 @@ typedef struct MovieTrackingSettings {
|
||||
|
||||
/* ** reconstruction settings ** */
|
||||
int keyframe1 DNA_DEPRECATED,
|
||||
keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization
|
||||
keyframe2 DNA_DEPRECATED; /* two keyframes for reconstruction initialization
|
||||
* were moved to per-tracking object settings
|
||||
*/
|
||||
|
||||
@@ -228,7 +228,7 @@ typedef struct MovieTrackingObject {
|
||||
MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */
|
||||
|
||||
/* reconstruction options */
|
||||
int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */
|
||||
int keyframe1, keyframe2; /* two keyframes for reconstruction initialization */
|
||||
} MovieTrackingObject;
|
||||
|
||||
typedef struct MovieTrackingStats {
|
||||
|
||||
@@ -1424,7 +1424,7 @@ static void rna_def_curve(BlenderRNA *brna)
|
||||
|
||||
prop = RNA_def_property(srna, "use_map_taper", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_MAP_TAPER);
|
||||
RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually bevelled curve");
|
||||
RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually beveled curve");
|
||||
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
|
||||
|
||||
/* texture space */
|
||||
|
||||
@@ -555,7 +555,7 @@ static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
|
||||
if (value.data == NULL)
|
||||
return;
|
||||
|
||||
/* exception: can't set screens inside of area/region handers */
|
||||
/* exception: can't set screens inside of area/region handlers */
|
||||
win->newscreen = value.data;
|
||||
}
|
||||
|
||||
@@ -563,8 +563,8 @@ static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
wmWindow *win = (wmWindow *)ptr->data;
|
||||
|
||||
/* exception: can't set screens inside of area/region handers, and must
|
||||
* use context so notifier gets to the right window */
|
||||
/* exception: can't set screens inside of area/region handlers,
|
||||
* and must use context so notifier gets to the right window */
|
||||
if (win->newscreen) {
|
||||
WM_event_add_notifier(C, NC_SCREEN | ND_SCREENBROWSE, win->newscreen);
|
||||
win->newscreen = NULL;
|
||||
|
||||
@@ -2784,7 +2784,7 @@ static struct PyMethodDef Vector_methods[] = {
|
||||
/* Note
|
||||
* Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
|
||||
* but this means for eg that
|
||||
* (vec * mat) and (mat * vec) both get sent to Vector_mul and it neesd to sort out the order
|
||||
* (vec * mat) and (mat * vec) both get sent to Vector_mul and it needs to sort out the order
|
||||
*/
|
||||
|
||||
PyDoc_STRVAR(vector_doc,
|
||||
|
||||
@@ -60,6 +60,7 @@ struct Scene;
|
||||
#define RE_ENGINE_PREVIEW 2
|
||||
#define RE_ENGINE_DO_DRAW 4
|
||||
#define RE_ENGINE_DO_UPDATE 8
|
||||
#define RE_ENGINE_RENDERING 16
|
||||
|
||||
extern ListBase R_engines;
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ int RE_rayobjectcontrol_test_break(RayObjectControl *c);
|
||||
* eg.: on render code)
|
||||
*
|
||||
* 0 means it's reserved and has it own meaning inside each ray acceleration structure
|
||||
* (this way each structure can use the allign offset to determine if a node represents a
|
||||
* (this way each structure can use the align offset to determine if a node represents a
|
||||
* RayObject primitive, which can be used to save memory)
|
||||
*/
|
||||
|
||||
|
||||
@@ -1026,7 +1026,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
|
||||
|
||||
labdao = ddalabda;
|
||||
|
||||
/* traversing ocree nodes need careful detection of smallest values, with proper
|
||||
/* traversing octree nodes need careful detection of smallest values, with proper
|
||||
* exceptions for equal labdas */
|
||||
eqval = (labdax == labday);
|
||||
if (labday == labdaz) eqval += 2;
|
||||
|
||||
@@ -435,7 +435,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
|
||||
/*
|
||||
* Helper code
|
||||
* PARTITION code / used on mean-split
|
||||
* basicly this a std::nth_element (like on C++ STL algorithm)
|
||||
* basically this a std::nth_element (like on C++ STL algorithm)
|
||||
*/
|
||||
#if 0
|
||||
static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
|
||||
|
||||
@@ -316,6 +316,7 @@ int RE_engine_render(Render *re, int do_all)
|
||||
{
|
||||
RenderEngineType *type = RE_engines_find(re->r.engine);
|
||||
RenderEngine *engine;
|
||||
int persistent_data = re->r.mode & R_PERSISTENT_DATA;
|
||||
|
||||
/* verify if we can render */
|
||||
if (!type->render)
|
||||
@@ -349,11 +350,17 @@ int RE_engine_render(Render *re, int do_all)
|
||||
re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0;
|
||||
|
||||
/* render */
|
||||
if (!re->engine)
|
||||
re->engine = RE_engine_create(type);
|
||||
|
||||
engine = re->engine;
|
||||
|
||||
if (!engine) {
|
||||
engine = RE_engine_create(type);
|
||||
|
||||
if (persistent_data)
|
||||
re->engine = engine;
|
||||
}
|
||||
|
||||
engine->flag |= RE_ENGINE_RENDERING;
|
||||
|
||||
/* TODO: actually link to a parent which shouldn't happen */
|
||||
engine->re = re;
|
||||
|
||||
@@ -382,8 +389,13 @@ int RE_engine_render(Render *re, int do_all)
|
||||
if (type->render)
|
||||
type->render(engine, re->scene);
|
||||
|
||||
if (!(re->r.mode & R_PERSISTENT_DATA)) {
|
||||
RE_engine_free(re->engine);
|
||||
engine->tile_x = 0;
|
||||
engine->tile_y = 0;
|
||||
engine->flag &= ~RE_ENGINE_RENDERING;
|
||||
|
||||
/* re->engine becomes zero if user changed active render engine during render */
|
||||
if (!persistent_data || !re->engine) {
|
||||
RE_engine_free(engine);
|
||||
re->engine = NULL;
|
||||
}
|
||||
|
||||
@@ -393,8 +405,6 @@ int RE_engine_render(Render *re, int do_all)
|
||||
BLI_rw_mutex_unlock(&re->resultmutex);
|
||||
}
|
||||
|
||||
engine->tile_x = 0;
|
||||
engine->tile_y = 0;
|
||||
freeparts(re);
|
||||
|
||||
render_result_free_list(&engine->fullresult, engine->fullresult.first);
|
||||
|
||||
@@ -435,7 +435,10 @@ void RE_FreePersistentData(void)
|
||||
/* render engines can be kept around for quick re-render, this clears all */
|
||||
for (re = RenderGlobal.renderlist.first; re; re = re->next) {
|
||||
if (re->engine) {
|
||||
RE_engine_free(re->engine);
|
||||
/* if engine is currently rendering, just tag it to be freed when render is finished */
|
||||
if (!(re->engine->flag & RE_ENGINE_RENDERING))
|
||||
RE_engine_free(re->engine);
|
||||
|
||||
re->engine = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
|
||||
|
||||
/**
|
||||
* PerezFunction:
|
||||
* compute perez function value based on input paramters
|
||||
* */
|
||||
* compute perez function value based on input parameters
|
||||
*/
|
||||
static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz)
|
||||
{
|
||||
float den, num;
|
||||
|
||||
@@ -545,7 +545,7 @@ static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKe
|
||||
|
||||
/* copy new keymap from an existing one */
|
||||
if (usermap && !(usermap->flag & KEYMAP_DIFF)) {
|
||||
/* for compatibiltiy with old user preferences with non-diff
|
||||
/* for compatibility with old user preferences with non-diff
|
||||
* keymaps we override the original entirely */
|
||||
wmKeyMapItem *kmi, *orig_kmi;
|
||||
|
||||
|
||||
@@ -624,7 +624,7 @@ void WM_operator_properties_sanitize(PointerRNA *ptr, const short no_context)
|
||||
/** set all props to their default,
|
||||
* \param do_update Only update un-initialized props.
|
||||
*
|
||||
* \note, theres nothing spesific to operators here.
|
||||
* \note, theres nothing specific to operators here.
|
||||
* this could be made a general function.
|
||||
*/
|
||||
int WM_operator_properties_default(PointerRNA *ptr, const int do_update)
|
||||
@@ -1186,6 +1186,8 @@ static void wm_operator_ui_popup_ok(struct bContext *C, void *arg, int retval)
|
||||
|
||||
if (op && retval > 0)
|
||||
WM_operator_call(C, op);
|
||||
|
||||
MEM_freeN(data);
|
||||
}
|
||||
|
||||
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
|
||||
@@ -1280,6 +1282,31 @@ static void WM_OT_debug_menu(wmOperatorType *ot)
|
||||
RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000);
|
||||
}
|
||||
|
||||
/* ***************** Operator defaults ************************* */
|
||||
static int wm_operator_defaults_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "active_operator", &RNA_Operator);
|
||||
|
||||
if (!ptr.data) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No operator in context");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
WM_operator_properties_reset((wmOperator *)ptr.data);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* used by operator preset menu. pre-2.65 this was a 'Reset' button */
|
||||
static void WM_OT_operator_defaults(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Restore Defaults";
|
||||
ot->idname = "WM_OT_operator_defaults";
|
||||
ot->description = "Set the active operator to its default values";
|
||||
|
||||
ot->exec = wm_operator_defaults_exec;
|
||||
|
||||
ot->flag = OPTYPE_INTERNAL;
|
||||
}
|
||||
|
||||
/* ***************** Splash Screen ************************* */
|
||||
|
||||
@@ -3748,6 +3775,7 @@ void wm_operatortype_init(void)
|
||||
WM_operatortype_append(WM_OT_memory_statistics);
|
||||
WM_operatortype_append(WM_OT_dependency_relations);
|
||||
WM_operatortype_append(WM_OT_debug_menu);
|
||||
WM_operatortype_append(WM_OT_operator_defaults);
|
||||
WM_operatortype_append(WM_OT_splash);
|
||||
WM_operatortype_append(WM_OT_search_menu);
|
||||
WM_operatortype_append(WM_OT_call_menu);
|
||||
|
||||
@@ -351,7 +351,7 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
|
||||
(GHOST_TWindowState)win->windowstate,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
0 /* no stereo */,
|
||||
multisamples /* AA */);
|
||||
multisamples /* AA */);
|
||||
|
||||
if (ghostwin) {
|
||||
/* needed so we can detect the graphics card below */
|
||||
|
||||
@@ -1693,8 +1693,8 @@ PyMethodDef KX_GameObject::Methods[] = {
|
||||
PyAttributeDef KX_GameObject::Attributes[] = {
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("group_children", KX_GameObject, pyattr_get_group_children),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("group_parent", KX_GameObject, pyattr_get_group_parent),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("groupMembers", KX_GameObject, pyattr_get_group_members),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("groupObject", KX_GameObject, pyattr_get_group_object),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("scene", KX_GameObject, pyattr_get_scene),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
|
||||
@@ -1991,7 +1991,7 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *KX_GameObject::pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
PyObject *KX_GameObject::pyattr_get_group_members(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
|
||||
CListValue* instances = self->GetInstanceObjects();
|
||||
@@ -2012,7 +2012,7 @@ PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *KX_GameObject::pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
PyObject *KX_GameObject::pyattr_get_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
|
||||
KX_GameObject* pivot = self->GetDupliGroupObject();
|
||||
|
||||
@@ -989,8 +989,8 @@ public:
|
||||
static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
static PyObject* pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_group_members(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_scene(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
@@ -76,7 +76,7 @@ PyMethodDef KX_MeshProxy::Methods[] = {
|
||||
{"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS},
|
||||
{"getPolygon", (PyCFunction)KX_MeshProxy::sPyGetPolygon,METH_VARARGS},
|
||||
{"transform", (PyCFunction)KX_MeshProxy::sPyTransform,METH_VARARGS},
|
||||
{"transform_uv", (PyCFunction)KX_MeshProxy::sPyTransformUV,METH_VARARGS},
|
||||
{"transformUV", (PyCFunction)KX_MeshProxy::sPyTransformUV,METH_VARARGS},
|
||||
//{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS},
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user