Merging r58073 through r58111 from trunk into soc-2013-depsgraph_mt
This commit is contained in:
@@ -462,6 +462,9 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
|
||||
mesh->name = ustring(b_ob_data.name().c_str());
|
||||
|
||||
if(render_layer.use_surfaces || render_layer.use_hair) {
|
||||
if(preview)
|
||||
b_ob.update_from_editmode();
|
||||
|
||||
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);
|
||||
|
||||
if(b_mesh) {
|
||||
|
||||
@@ -223,7 +223,7 @@ bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int
|
||||
float3 f = make_float3(in[0], in[1], in[2]);
|
||||
float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
|
||||
|
||||
f = safe_divide_color(f*exposure, f_divide);
|
||||
f = safe_divide_even_color(f*exposure, f_divide);
|
||||
|
||||
pixels[0] = f.x;
|
||||
pixels[1] = f.y;
|
||||
|
||||
@@ -1100,6 +1100,42 @@ __device_inline float3 safe_divide_color(float3 a, float3 b)
|
||||
return make_float3(x, y, z);
|
||||
}
|
||||
|
||||
__device_inline float3 safe_divide_even_color(float3 a, float3 b)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
x = (b.x != 0.0f)? a.x/b.x: 0.0f;
|
||||
y = (b.y != 0.0f)? a.y/b.y: 0.0f;
|
||||
z = (b.z != 0.0f)? a.z/b.z: 0.0f;
|
||||
|
||||
/* try to get grey even if b is zero */
|
||||
if(b.x == 0.0f) {
|
||||
if(b.y == 0.0f) {
|
||||
x = z;
|
||||
y = z;
|
||||
}
|
||||
else if(b.z == 0.0f) {
|
||||
x = y;
|
||||
z = y;
|
||||
}
|
||||
else
|
||||
x = 0.5f*(y + z);
|
||||
}
|
||||
else if(b.y == 0.0f) {
|
||||
if(b.z == 0.0f) {
|
||||
y = x;
|
||||
z = x;
|
||||
}
|
||||
else
|
||||
y = 0.5f*(x + z);
|
||||
}
|
||||
else if(b.z == 0.0f) {
|
||||
z = 0.5f*(x + y);
|
||||
}
|
||||
|
||||
return make_float3(x, y, z);
|
||||
}
|
||||
|
||||
/* Rotation of point around axis and angle */
|
||||
|
||||
__device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
|
||||
|
||||
@@ -1052,7 +1052,7 @@ class USERPREF_PT_input(Panel):
|
||||
row.separator()
|
||||
|
||||
def draw(self, context):
|
||||
from bl_ui.space_userpref_keymap import draw_keymaps
|
||||
from rna_keymap_ui import draw_keymaps
|
||||
|
||||
layout = self.layout
|
||||
|
||||
|
||||
@@ -75,7 +75,17 @@ struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
|
||||
void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
|
||||
void BKE_scene_base_deselect_all(struct Scene *sce);
|
||||
void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
|
||||
int BKE_scene_base_iter_next(struct Scene **scene, int val, struct Base **base, struct Object **ob);
|
||||
|
||||
/* Scene base iteration function.
|
||||
* Define struct here, so no need to bother with alloc/free it.
|
||||
*/
|
||||
typedef struct SceneBaseIter {
|
||||
struct ListBase *duplilist;
|
||||
struct DupliObject *dupob;
|
||||
int fase;
|
||||
} SceneBaseIter;
|
||||
|
||||
int BKE_scene_base_iter_next(struct SceneBaseIter *iter, struct Scene **scene, int val, struct Base **base, struct Object **ob);
|
||||
|
||||
void BKE_scene_base_flag_to_objects(struct Scene *scene);
|
||||
void BKE_scene_base_flag_from_objects(struct Scene *scene);
|
||||
|
||||
@@ -486,14 +486,15 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
|
||||
MetaBall *active_mball = (MetaBall *)active_object->data;
|
||||
int basisnr, obnr;
|
||||
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
|
||||
|
||||
SceneBaseIter iter;
|
||||
|
||||
BLI_split_name_num(basisname, &basisnr, active_object->id.name + 2, '.');
|
||||
|
||||
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
|
||||
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
|
||||
if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
|
||||
return;
|
||||
|
||||
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
|
||||
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
|
||||
if (ob->type == OB_MBALL) {
|
||||
if (ob != active_object) {
|
||||
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
|
||||
@@ -530,14 +531,15 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
|
||||
Object *ob, *bob = basis;
|
||||
int basisnr, obnr;
|
||||
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
|
||||
SceneBaseIter iter;
|
||||
|
||||
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
|
||||
|
||||
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
|
||||
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
|
||||
if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
|
||||
return NULL;
|
||||
|
||||
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
|
||||
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
|
||||
if (ob->type == OB_MBALL) {
|
||||
if (ob != bob) {
|
||||
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
|
||||
@@ -1656,7 +1658,8 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return
|
||||
//float max = 0.0f;
|
||||
int a, obnr, zero_size = 0;
|
||||
char obname[MAX_ID_NAME];
|
||||
|
||||
SceneBaseIter iter;
|
||||
|
||||
copy_m4_m4(obmat, ob->obmat); /* to cope with duplicators from BKE_scene_base_iter_next */
|
||||
invert_m4_m4(obinv, ob->obmat);
|
||||
a = 0;
|
||||
@@ -1664,8 +1667,8 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return
|
||||
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
|
||||
|
||||
/* make main array */
|
||||
BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL);
|
||||
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &bob)) {
|
||||
BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL);
|
||||
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &bob)) {
|
||||
|
||||
if (bob->type == OB_MBALL) {
|
||||
zero_size = 0;
|
||||
@@ -2226,15 +2229,16 @@ static void mball_count(PROCESS *process, Scene *scene, Object *basis)
|
||||
MetaElem *ml = NULL;
|
||||
int basisnr, obnr;
|
||||
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
|
||||
SceneBaseIter iter;
|
||||
|
||||
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
|
||||
process->totelem = 0;
|
||||
|
||||
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
|
||||
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
|
||||
if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
|
||||
return;
|
||||
|
||||
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
|
||||
while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
|
||||
if (ob->type == OB_MBALL) {
|
||||
if (ob == bob) {
|
||||
MetaBall *mb = ob->data;
|
||||
|
||||
@@ -747,17 +747,16 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
|
||||
/* used by metaballs
|
||||
* doesn't return the original duplicated object, only dupli's
|
||||
*/
|
||||
int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
|
||||
int BKE_scene_base_iter_next(SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
|
||||
{
|
||||
static ListBase *duplilist = NULL;
|
||||
static DupliObject *dupob;
|
||||
static int fase = F_START, in_next_object = 0;
|
||||
static ThreadVariable int in_next_object = 0;
|
||||
int run_again = 1;
|
||||
|
||||
/* init */
|
||||
if (val == 0) {
|
||||
fase = F_START;
|
||||
dupob = NULL;
|
||||
iter->fase = F_START;
|
||||
iter->dupob = NULL;
|
||||
iter->duplilist = NULL;
|
||||
|
||||
/* XXX particle systems with metas+dupligroups call this recursively */
|
||||
/* see bug #18725 */
|
||||
@@ -775,11 +774,11 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
|
||||
run_again = 0;
|
||||
|
||||
/* the first base */
|
||||
if (fase == F_START) {
|
||||
if (iter->fase == F_START) {
|
||||
*base = (*scene)->base.first;
|
||||
if (*base) {
|
||||
*ob = (*base)->object;
|
||||
fase = F_SCENE;
|
||||
iter->fase = F_SCENE;
|
||||
}
|
||||
else {
|
||||
/* exception: empty scene */
|
||||
@@ -788,20 +787,20 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
|
||||
if ((*scene)->base.first) {
|
||||
*base = (*scene)->base.first;
|
||||
*ob = (*base)->object;
|
||||
fase = F_SCENE;
|
||||
iter->fase = F_SCENE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (*base && fase != F_DUPLI) {
|
||||
if (*base && iter->fase != F_DUPLI) {
|
||||
*base = (*base)->next;
|
||||
if (*base) {
|
||||
*ob = (*base)->object;
|
||||
}
|
||||
else {
|
||||
if (fase == F_SCENE) {
|
||||
if (iter->fase == F_SCENE) {
|
||||
/* (*scene) is finished, now do the set */
|
||||
while ((*scene)->set) {
|
||||
(*scene) = (*scene)->set;
|
||||
@@ -817,45 +816,45 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
|
||||
}
|
||||
|
||||
if (*base == NULL) {
|
||||
fase = F_START;
|
||||
iter->fase = F_START;
|
||||
}
|
||||
else {
|
||||
if (fase != F_DUPLI) {
|
||||
if (iter->fase != F_DUPLI) {
|
||||
if ( (*base)->object->transflag & OB_DUPLI) {
|
||||
/* groups cannot be duplicated for mballs yet,
|
||||
* this enters eternal loop because of
|
||||
* makeDispListMBall getting called inside of group_duplilist */
|
||||
if ((*base)->object->dup_group == NULL) {
|
||||
duplilist = object_duplilist((*scene), (*base)->object, FALSE);
|
||||
iter->duplilist = object_duplilist((*scene), (*base)->object, FALSE);
|
||||
|
||||
dupob = duplilist->first;
|
||||
iter->dupob = iter->duplilist->first;
|
||||
|
||||
if (!dupob)
|
||||
free_object_duplilist(duplilist);
|
||||
if (!iter->dupob)
|
||||
free_object_duplilist(iter->duplilist);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* handle dupli's */
|
||||
if (dupob) {
|
||||
if (iter->dupob) {
|
||||
|
||||
copy_m4_m4(dupob->ob->obmat, dupob->mat);
|
||||
copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat);
|
||||
|
||||
(*base)->flag |= OB_FROMDUPLI;
|
||||
*ob = dupob->ob;
|
||||
fase = F_DUPLI;
|
||||
*ob = iter->dupob->ob;
|
||||
iter->fase = F_DUPLI;
|
||||
|
||||
dupob = dupob->next;
|
||||
iter->dupob = iter->dupob->next;
|
||||
}
|
||||
else if (fase == F_DUPLI) {
|
||||
fase = F_SCENE;
|
||||
else if (iter->fase == F_DUPLI) {
|
||||
iter->fase = F_SCENE;
|
||||
(*base)->flag &= ~OB_FROMDUPLI;
|
||||
|
||||
for (dupob = duplilist->first; dupob; dupob = dupob->next) {
|
||||
copy_m4_m4(dupob->ob->obmat, dupob->omat);
|
||||
for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) {
|
||||
copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->omat);
|
||||
}
|
||||
|
||||
free_object_duplilist(duplilist);
|
||||
duplilist = NULL;
|
||||
free_object_duplilist(iter->duplilist);
|
||||
iter->duplilist = NULL;
|
||||
run_again = 1;
|
||||
}
|
||||
}
|
||||
@@ -871,7 +870,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
|
||||
/* reset recursion test */
|
||||
in_next_object = 0;
|
||||
|
||||
return fase;
|
||||
return iter->fase;
|
||||
}
|
||||
|
||||
Object *BKE_scene_camera_find(Scene *sc)
|
||||
|
||||
@@ -847,19 +847,6 @@ int txt_utf8_column_to_offset(const char *str, int column)
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* returns the real number of characters in string */
|
||||
/* not the same as BLI_strlen_utf8, which returns length for wide characters */
|
||||
static int txt_utf8_len(const char *src)
|
||||
{
|
||||
int len;
|
||||
|
||||
for (len = 0; *src; len++) {
|
||||
src += BLI_str_utf8_size(src);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void txt_move_up(Text *text, short sel)
|
||||
{
|
||||
TextLine **linep;
|
||||
@@ -2059,7 +2046,7 @@ void txt_do_undo(Text *text)
|
||||
text->undo_pos--;
|
||||
}
|
||||
buf[i] = 0;
|
||||
linep = txt_utf8_len(buf);
|
||||
linep = BLI_strlen_utf8(buf);
|
||||
MEM_freeN(buf);
|
||||
|
||||
/* skip over the length that was stored again */
|
||||
|
||||
@@ -51,8 +51,10 @@ char *BLI_str_prev_char_utf8(const char *p);
|
||||
|
||||
/* wchar_t functions, copied from blenders own font.c originally */
|
||||
size_t BLI_wstrlen_utf8(const wchar_t *src);
|
||||
size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes);
|
||||
size_t BLI_strlen_utf8(const char *strc);
|
||||
size_t BLI_strnlen_utf8(const char *start, const size_t maxlen);
|
||||
size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes);
|
||||
size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen);
|
||||
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
|
||||
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
|
||||
|
||||
|
||||
@@ -132,6 +132,18 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex);
|
||||
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode);
|
||||
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex);
|
||||
|
||||
/* Ticket Mutex Lock
|
||||
*
|
||||
* This is a 'fair' mutex in that it will grant the lock to the first thread
|
||||
* that requests it. */
|
||||
|
||||
typedef struct TicketMutex TicketMutex;
|
||||
|
||||
TicketMutex *BLI_ticket_mutex_alloc(void);
|
||||
void BLI_ticket_mutex_free(TicketMutex *ticket);
|
||||
void BLI_ticket_mutex_lock(TicketMutex *ticket);
|
||||
void BLI_ticket_mutex_unlock(TicketMutex *ticket);
|
||||
|
||||
/* ThreadedWorker
|
||||
*
|
||||
* A simple tool for dispatching work to a limited number of threads
|
||||
@@ -181,6 +193,13 @@ void BLI_condition_notify_one(ThreadCondition *cond);
|
||||
void BLI_condition_notify_all(ThreadCondition *cond);
|
||||
void BLI_condition_end(ThreadCondition *cond);
|
||||
|
||||
/* Thread Local Storage */
|
||||
#ifdef _MSC_VER
|
||||
# define ThreadVariable __declspec(thread)
|
||||
#else
|
||||
# define ThreadVariable __thread
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -245,24 +245,16 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* this is very close to 'BLI_str_utf8_size' functionality, perhaps we should de-duplicate */
|
||||
/* size of UTF-8 character in bytes */
|
||||
static size_t strlen_utf8_char(const char *strc)
|
||||
size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes)
|
||||
{
|
||||
if ((*strc & 0xe0) == 0xc0) {
|
||||
if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
|
||||
return 2;
|
||||
}
|
||||
else if ((*strc & 0xf0) == 0xe0) {
|
||||
if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
|
||||
return 3;
|
||||
}
|
||||
else if ((*strc & 0xf8) == 0xf0) {
|
||||
if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
|
||||
return 4;
|
||||
}
|
||||
size_t len;
|
||||
const char *strc_orig = strc;
|
||||
|
||||
return 1;
|
||||
for (len = 0; *strc; len++)
|
||||
strc += BLI_str_utf8_size_safe(strc);
|
||||
|
||||
*r_len_bytes = (strc - strc_orig);
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t BLI_strlen_utf8(const char *strc)
|
||||
@@ -270,25 +262,37 @@ size_t BLI_strlen_utf8(const char *strc)
|
||||
size_t len;
|
||||
|
||||
for (len = 0; *strc; len++)
|
||||
strc += strlen_utf8_char(strc);
|
||||
strc += BLI_str_utf8_size_safe(strc);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes)
|
||||
{
|
||||
size_t len;
|
||||
const char *strc_orig = strc;
|
||||
const char *strc_end = strc + maxlen;
|
||||
|
||||
for (len = 0; *strc && strc < strc_end; len++) {
|
||||
strc += BLI_str_utf8_size_safe(strc);
|
||||
}
|
||||
|
||||
*r_len_bytes = (strc - strc_orig);
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param start the string to measure the length.
|
||||
* \param maxlen the string length (in bytes)
|
||||
* \return the unicode length (not in bytes!)
|
||||
*/
|
||||
size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
|
||||
size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
|
||||
{
|
||||
const char *strc = start;
|
||||
const char *strc_end = start + maxlen;
|
||||
|
||||
size_t len;
|
||||
const char *strc_end = strc + maxlen;
|
||||
|
||||
for (len = 0; *strc && strc < strc_end; len++) {
|
||||
strc += strlen_utf8_char(strc);
|
||||
strc += BLI_str_utf8_size_safe(strc);
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
@@ -513,6 +513,52 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex)
|
||||
MEM_freeN(mutex);
|
||||
}
|
||||
|
||||
/* Ticket Mutex Lock */
|
||||
|
||||
struct TicketMutex {
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
unsigned int queue_head, queue_tail;
|
||||
};
|
||||
|
||||
TicketMutex *BLI_ticket_mutex_alloc(void)
|
||||
{
|
||||
TicketMutex *ticket = MEM_callocN(sizeof(TicketMutex), "TicketMutex");
|
||||
|
||||
pthread_cond_init(&ticket->cond, NULL);
|
||||
pthread_mutex_init(&ticket->mutex, NULL);
|
||||
|
||||
return ticket;
|
||||
}
|
||||
|
||||
void BLI_ticket_mutex_free(TicketMutex *ticket)
|
||||
{
|
||||
pthread_mutex_destroy(&ticket->mutex);
|
||||
pthread_cond_destroy(&ticket->cond);
|
||||
MEM_freeN(ticket);
|
||||
}
|
||||
|
||||
void BLI_ticket_mutex_lock(TicketMutex *ticket)
|
||||
{
|
||||
unsigned int queue_me;
|
||||
|
||||
pthread_mutex_lock(&ticket->mutex);
|
||||
queue_me = ticket->queue_tail++;
|
||||
|
||||
while (queue_me != ticket->queue_head)
|
||||
pthread_cond_wait(&ticket->cond, &ticket->mutex);
|
||||
|
||||
pthread_mutex_unlock(&ticket->mutex);
|
||||
}
|
||||
|
||||
void BLI_ticket_mutex_unlock(TicketMutex *ticket)
|
||||
{
|
||||
pthread_mutex_lock(&ticket->mutex);
|
||||
ticket->queue_head++;
|
||||
pthread_cond_broadcast(&ticket->cond);
|
||||
pthread_mutex_unlock(&ticket->mutex);
|
||||
}
|
||||
|
||||
/* ************************************************ */
|
||||
|
||||
typedef struct ThreadedWorker {
|
||||
|
||||
@@ -5707,8 +5707,9 @@ static void lib_link_screen(FileData *fd, Main *main)
|
||||
ntree = nodetree_from_id(snode->id);
|
||||
if (ntree)
|
||||
snode->nodetree = ntree;
|
||||
else
|
||||
snode->nodetree = newlibadr(fd, sc->id.lib, snode->nodetree);
|
||||
else {
|
||||
snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree);
|
||||
}
|
||||
|
||||
for (path = snode->treepath.first; path; path = path->next) {
|
||||
if (path == snode->treepath.first) {
|
||||
@@ -5716,7 +5717,7 @@ static void lib_link_screen(FileData *fd, Main *main)
|
||||
path->nodetree = snode->nodetree;
|
||||
}
|
||||
else
|
||||
path->nodetree = newlibadr(fd, sc->id.lib, path->nodetree);
|
||||
path->nodetree = newlibadr_us(fd, sc->id.lib, path->nodetree);
|
||||
|
||||
if (!path->nodetree)
|
||||
break;
|
||||
@@ -6045,7 +6046,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
|
||||
path->nodetree = snode->nodetree;
|
||||
}
|
||||
else
|
||||
path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 0);
|
||||
path->nodetree= restore_pointer_by_name(newmain, (ID*)path->nodetree, 2);
|
||||
|
||||
if (!path->nodetree)
|
||||
break;
|
||||
|
||||
@@ -1642,13 +1642,6 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
|
||||
}
|
||||
}
|
||||
|
||||
static int amount_of_chars(char *str)
|
||||
{
|
||||
// Since the data is saved as UTF-8 to the cu->str
|
||||
// The cu->len is not same as the strlen(cu->str)
|
||||
return strlen(str);
|
||||
}
|
||||
|
||||
static void write_curves(WriteData *wd, ListBase *idbase)
|
||||
{
|
||||
Curve *cu;
|
||||
@@ -1666,8 +1659,12 @@ static void write_curves(WriteData *wd, ListBase *idbase)
|
||||
if (cu->adt) write_animdata(wd, cu->adt);
|
||||
|
||||
if (cu->vfont) {
|
||||
writedata(wd, DATA, amount_of_chars(cu->str)+1, cu->str);
|
||||
writestruct(wd, DATA, "CharInfo", cu->len+1, cu->strinfo);
|
||||
/* TODO, sort out 'cu->len', in editmode its character, object mode its bytes */
|
||||
int len_bytes;
|
||||
int len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes);
|
||||
|
||||
writedata(wd, DATA, len_bytes + 1, cu->str);
|
||||
writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo);
|
||||
writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1758,6 +1758,119 @@ float BM_mesh_calc_volume(BMesh *bm, bool is_signed)
|
||||
return vol;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO (as we need)
|
||||
* - option to walk over faces by verts.
|
||||
* - option to walk over non manifold edges.
|
||||
*
|
||||
* \param bm the BMesh.
|
||||
* \param r_groups_array Array of ints to fill in, length of bm->totface.
|
||||
* \param r_group_index index, length pairs into \a r_groups_array, size of return value
|
||||
* int pairs: (array_start, array_length).
|
||||
* \return The number of groups found.
|
||||
*/
|
||||
int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
|
||||
void *user_data, bool (*filter_fn)(BMEdge *, void *user_data))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
int group_index_len = 1;
|
||||
#else
|
||||
int group_index_len = 32;
|
||||
#endif
|
||||
|
||||
int (*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__);
|
||||
|
||||
int *group_array = r_groups_array;
|
||||
STACK_DECLARE(group_array);
|
||||
|
||||
int group_curr = 0;
|
||||
|
||||
const unsigned int tot_faces = bm->totface;
|
||||
unsigned int tot_touch = 0;
|
||||
|
||||
BMFace **fstack;
|
||||
STACK_DECLARE(fstack);
|
||||
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
int i;
|
||||
|
||||
STACK_INIT(group_array);
|
||||
|
||||
/* init the array */
|
||||
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
BM_elem_index_set(f, i); /* set_inline */
|
||||
BM_elem_flag_disable(f, BM_ELEM_TAG);
|
||||
}
|
||||
bm->elem_index_dirty &= ~BM_FACE;
|
||||
|
||||
/* detect groups */
|
||||
fstack = MEM_mallocN(sizeof(*fstack) * tot_faces, __func__);
|
||||
|
||||
while (tot_touch != tot_faces) {
|
||||
int *fg;
|
||||
bool ok = false;
|
||||
|
||||
BLI_assert(tot_touch < tot_faces);
|
||||
|
||||
STACK_INIT(fstack);
|
||||
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) {
|
||||
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
||||
STACK_PUSH(fstack, f);
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert(ok == true);
|
||||
|
||||
/* manage arrays */
|
||||
if (group_index_len == group_curr) {
|
||||
group_index_len *= 2;
|
||||
group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
|
||||
}
|
||||
|
||||
fg = group_index[group_curr];
|
||||
fg[0] = STACK_SIZE(group_array);
|
||||
fg[1] = 0;
|
||||
|
||||
while ((f = STACK_POP(fstack))) {
|
||||
BMLoop *l_iter, *l_first;
|
||||
|
||||
/* add face */
|
||||
STACK_PUSH(group_array, BM_elem_index_get(f));
|
||||
tot_touch++;
|
||||
fg[1]++;
|
||||
/* done */
|
||||
|
||||
/* search for other faces */
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BMLoop *l_other = l_iter->radial_next;
|
||||
if ((l_other != l_iter) && filter_fn(l_iter->e, user_data)) {
|
||||
if (BM_elem_flag_test(l_other->f, BM_ELEM_TAG) == false) {
|
||||
BM_elem_flag_enable(l_other->f, BM_ELEM_TAG);
|
||||
STACK_PUSH(fstack, l_other->f);
|
||||
}
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
}
|
||||
|
||||
group_curr++;
|
||||
}
|
||||
|
||||
MEM_freeN(fstack);
|
||||
|
||||
/* reduce alloc to required size */
|
||||
group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
|
||||
*r_group_index = group_index;
|
||||
|
||||
return group_curr;
|
||||
}
|
||||
|
||||
float bmesh_subd_falloff_calc(const int falloff, float val)
|
||||
{
|
||||
switch (falloff) {
|
||||
|
||||
@@ -115,6 +115,8 @@ bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
|
||||
bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
|
||||
|
||||
float BM_mesh_calc_volume(BMesh *bm, bool is_signed);
|
||||
int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
|
||||
void *user_data, bool (*filter_fn)(BMEdge *, void *user_data));
|
||||
|
||||
/* not really any good place to put this */
|
||||
float bmesh_subd_falloff_calc(const int falloff, float val);
|
||||
|
||||
@@ -36,8 +36,105 @@
|
||||
|
||||
/********* righthand faces implementation ****** */
|
||||
|
||||
#define FACE_VIS 1
|
||||
#define FACE_FLAG 2
|
||||
#define FACE_FLAG (1 << 0)
|
||||
#define FACE_FLIP (1 << 1)
|
||||
#define FACE_TEMP (1 << 2)
|
||||
|
||||
static bool bmo_recalc_normal_edge_filter_cb(BMEdge *e, void *UNUSED(user_data))
|
||||
{
|
||||
return BM_edge_is_manifold(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array of faces, recalcualte their normals.
|
||||
* this functions assumes all faces in the array are connected by edges.
|
||||
*
|
||||
* \param bm
|
||||
* \param faces Array of connected faces.
|
||||
* \param faces_len Length of \a faces
|
||||
* \param oflag Flag to check before doing the actual face flipping.
|
||||
*/
|
||||
static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int faces_len, const short oflag)
|
||||
{
|
||||
float cent[3], tvec[3];
|
||||
float (*faces_center)[3] = MEM_mallocN(sizeof(*faces_center) * faces_len, __func__);
|
||||
const float cent_fac = 1.0f / (float)faces_len;
|
||||
int i, f_start_index;
|
||||
const short oflag_flip = oflag | FACE_FLIP;
|
||||
|
||||
float f_len_best;
|
||||
BMFace *f;
|
||||
|
||||
BMFace **fstack = MEM_mallocN(sizeof(*fstack) * faces_len, __func__);
|
||||
STACK_DECLARE(fstack);
|
||||
|
||||
zero_v3(cent);
|
||||
|
||||
/* first calculate the center */
|
||||
for (i = 0; i < faces_len; i++) {
|
||||
float *f_cent = faces_center[i];
|
||||
BM_face_calc_center_mean_weighted(faces[i], f_cent);
|
||||
madd_v3_v3fl(cent, f_cent, cent_fac);
|
||||
|
||||
BLI_assert(BMO_elem_flag_test(bm, faces[i], FACE_TEMP) == 0);
|
||||
}
|
||||
|
||||
f_len_best = -FLT_MAX;
|
||||
|
||||
for (i = 0; i < faces_len; i++) {
|
||||
float f_len_test;
|
||||
|
||||
if ((f_len_test = len_squared_v3v3(faces_center[i], cent)) > f_len_best) {
|
||||
f_len_best = f_len_test;
|
||||
f_start_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure the starting face has the correct winding */
|
||||
sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
|
||||
if (dot_v3v3(tvec, faces[f_start_index]->no) < 0.0f) {
|
||||
BMO_elem_flag_enable(bm, faces[f_start_index], FACE_FLIP);
|
||||
}
|
||||
|
||||
MEM_freeN(faces_center);
|
||||
|
||||
/* now that we've found our starting face, make all connected faces
|
||||
* have the same winding. this is done recursively, using a manual
|
||||
* stack (if we use simple function recursion, we'd end up overloading
|
||||
* the stack on large meshes). */
|
||||
STACK_INIT(fstack);
|
||||
|
||||
STACK_PUSH(fstack, faces[f_start_index]);
|
||||
BMO_elem_flag_enable(bm, faces[f_start_index], FACE_TEMP);
|
||||
|
||||
while ((f = STACK_POP(fstack))) {
|
||||
const bool flip_state = BMO_elem_flag_test_bool(bm, f, FACE_FLIP);
|
||||
BMLoop *l_iter, *l_first;
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BMLoop *l_other = l_iter->radial_next;
|
||||
|
||||
if ((l_other != l_iter) && bmo_recalc_normal_edge_filter_cb(l_iter->e, NULL)) {
|
||||
if (!BMO_elem_flag_test(bm, l_other->f, FACE_TEMP)) {
|
||||
BMO_elem_flag_enable(bm, l_other->f, FACE_TEMP);
|
||||
BMO_elem_flag_set(bm, l_other->f, FACE_FLIP, (l_other->v == l_iter->v) != flip_state);
|
||||
STACK_PUSH(fstack, l_other->f);
|
||||
}
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
}
|
||||
|
||||
MEM_freeN(fstack);
|
||||
|
||||
/* apply flipping to oflag'd faces */
|
||||
for (i = 0; i < faces_len; i++) {
|
||||
if (BMO_elem_flag_test(bm, faces[i], oflag_flip) == oflag_flip) {
|
||||
BM_face_normal_flip(bm, faces[i]);
|
||||
}
|
||||
BMO_elem_flag_disable(bm, faces[i], FACE_TEMP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* put normal to the outside, and set the first direction flags in edges
|
||||
@@ -47,92 +144,44 @@
|
||||
*
|
||||
* in case all faces were not done: start over with 'find the ultimate ...' */
|
||||
|
||||
/* NOTE: BM_ELEM_TAG is used on faces to tell if they are flipped. */
|
||||
|
||||
void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMFace **fstack;
|
||||
STACK_DECLARE(fstack);
|
||||
const unsigned int tot_faces = BMO_slot_buffer_count(op->slots_in, "faces");
|
||||
unsigned int tot_touch = 0;
|
||||
int *groups_array = MEM_mallocN(sizeof(groups_array) * bm->totface, __func__);
|
||||
int faces_len;
|
||||
BMFace **faces_arr = BM_iter_as_arrayN(bm, BM_FACES_OF_MESH, NULL, &faces_len, NULL, 0);
|
||||
BMFace **faces_grp = MEM_mallocN(sizeof(faces_grp) * bm->totface, __func__);
|
||||
|
||||
int (*group_index)[2];
|
||||
const int group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index,
|
||||
NULL, bmo_recalc_normal_edge_filter_cb);
|
||||
int i;
|
||||
|
||||
|
||||
BMO_slot_buffer_flag_enable(bm, op->slots_in, "faces", BM_FACE, FACE_FLAG);
|
||||
|
||||
fstack = MEM_mallocN(sizeof(*fstack) * tot_faces, __func__);
|
||||
for (i = 0; i < group_tot; i++) {
|
||||
const int fg_sta = group_index[i][0];
|
||||
const int fg_len = group_index[i][1];
|
||||
int j;
|
||||
bool is_calc = false;
|
||||
|
||||
while (tot_touch != tot_faces) {
|
||||
BMOIter siter;
|
||||
float f_len_best = -FLT_MAX;
|
||||
BMFace *f, *f_start = NULL;
|
||||
float f_start_cent[3];
|
||||
for (j = 0; j < fg_len; j++) {
|
||||
faces_grp[j] = faces_arr[groups_array[fg_sta + j]];
|
||||
|
||||
/* find a starting face */
|
||||
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
|
||||
float f_cent[3];
|
||||
float f_len_test;
|
||||
|
||||
/* clear dirty flag */
|
||||
BM_elem_flag_disable(f, BM_ELEM_TAG);
|
||||
|
||||
if (BMO_elem_flag_test(bm, f, FACE_VIS))
|
||||
continue;
|
||||
|
||||
if (!f_start) f_start = f;
|
||||
|
||||
BM_face_calc_center_bounds(f, f_cent);
|
||||
|
||||
if ((f_len_test = len_squared_v3(f_cent)) > f_len_best) {
|
||||
f_len_best = f_len_test;
|
||||
f_start = f;
|
||||
copy_v3_v3(f_start_cent, f_cent);
|
||||
if (is_calc == false) {
|
||||
is_calc = BMO_elem_flag_test_bool(bm, faces_grp[j], FACE_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
/* check sanity (while loop ensures) */
|
||||
BLI_assert(f_start != NULL);
|
||||
|
||||
/* make sure the starting face has the correct winding */
|
||||
if (dot_v3v3(f_start_cent, f_start->no) < 0.0f) {
|
||||
BM_face_normal_flip(bm, f_start);
|
||||
}
|
||||
|
||||
/* now that we've found our starting face, make all connected faces
|
||||
* have the same winding. this is done recursively, using a manual
|
||||
* stack (if we use simple function recursion, we'd end up overloading
|
||||
* the stack on large meshes). */
|
||||
STACK_INIT(fstack);
|
||||
|
||||
STACK_PUSH(fstack, f_start);
|
||||
BMO_elem_flag_enable(bm, f_start, FACE_VIS);
|
||||
tot_touch++;
|
||||
|
||||
while ((f = STACK_POP(fstack))) {
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
|
||||
BMLoop *l_other = l->radial_next;
|
||||
|
||||
if ((l_other == l) || l_other->radial_next != l) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BMO_elem_flag_test(bm, l_other->f, FACE_FLAG)) {
|
||||
if (!BMO_elem_flag_test(bm, l_other->f, FACE_VIS)) {
|
||||
BMO_elem_flag_enable(bm, l_other->f, FACE_VIS);
|
||||
tot_touch++;
|
||||
|
||||
|
||||
if (l_other->v == l->v) {
|
||||
BM_face_normal_flip(bm, l_other->f);
|
||||
}
|
||||
|
||||
STACK_PUSH(fstack, l_other->f);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_calc) {
|
||||
bmo_recalc_face_normals_array(bm, faces_grp, fg_len, FACE_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(fstack);
|
||||
|
||||
if (faces_arr) MEM_freeN(faces_arr);
|
||||
MEM_freeN(faces_grp);
|
||||
|
||||
MEM_freeN(groups_array);
|
||||
MEM_freeN(group_index);
|
||||
}
|
||||
|
||||
@@ -2223,6 +2223,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
|
||||
BMVert *bmv1, *bmv2, *bmv3, *bmv4, *bmv1i, *bmv2i, *bmv3i, *bmv4i;
|
||||
VMesh *vm1, *vm2;
|
||||
EdgeHalf *e1, *e2;
|
||||
BMEdge *bme1, *bme2;
|
||||
BMFace *f1, *f2, *f;
|
||||
int k, nseg, i1, i2, odd, mid;
|
||||
|
||||
@@ -2294,6 +2295,13 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
|
||||
bev_merge_end_uvs(bm, bv1, e1);
|
||||
if (!e2->is_seam && bv2->vmesh->mesh_kind == M_NONE)
|
||||
bev_merge_end_uvs(bm, bv2, e2);
|
||||
|
||||
/* Copy edge data to first and last edge */
|
||||
bme1 = BM_edge_exists(bmv1, bmv2);
|
||||
bme2 = BM_edge_exists(bmv3, bmv4);
|
||||
BLI_assert(bme1 && bme2);
|
||||
BM_elem_attrs_copy(bm, bm, bme, bme1);
|
||||
BM_elem_attrs_copy(bm, bm, bme, bme2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -52,6 +52,8 @@ void ED_render_engine_changed(struct Main *bmain);
|
||||
void ED_render_engine_area_exit(struct ScrArea *sa);
|
||||
void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated);
|
||||
|
||||
void ED_viewport_render_kill_jobs(const struct bContext *C);
|
||||
|
||||
/* render_preview.c */
|
||||
|
||||
/* stores rendered preview - is also used for icons */
|
||||
|
||||
@@ -2167,6 +2167,15 @@ static void ui_set_but_soft_range(uiBut *but)
|
||||
but->softmin = softmin;
|
||||
but->softmax = softmax;
|
||||
}
|
||||
else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
|
||||
float value = ui_get_but_val(but);
|
||||
CLAMP(value, but->hardmin, but->hardmax);
|
||||
but->softmin = min_ff(but->softmin, value);
|
||||
but->softmax = max_ff(but->softmax, value);
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************* Free ********************/
|
||||
@@ -2368,8 +2377,12 @@ void ui_check_but(uiBut *but)
|
||||
ui_check_but_select(but, &value);
|
||||
|
||||
/* only update soft range while not editing */
|
||||
if (but->rnaprop && !(but->editval || but->editstr || but->editvec)) {
|
||||
ui_set_but_soft_range(but);
|
||||
if (!(but->editval || but->editstr || but->editvec)) {
|
||||
if ((but->rnaprop != NULL) ||
|
||||
(but->poin && (but->pointype & UI_BUT_POIN_TYPES)))
|
||||
{
|
||||
ui_set_but_soft_range(but);
|
||||
}
|
||||
}
|
||||
|
||||
/* test for min and max, icon sliders, etc */
|
||||
@@ -2757,13 +2770,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
|
||||
uiBut *but;
|
||||
int slen;
|
||||
|
||||
BLI_assert(width >= 0);
|
||||
BLI_assert(height >= 0);
|
||||
BLI_assert(width >= 0 && height >= 0);
|
||||
|
||||
/* we could do some more error checks here */
|
||||
if ((type & BUTTYPE) == LABEL) {
|
||||
if ((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)))
|
||||
printf("blah\n");
|
||||
BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -2116,7 +2116,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
|
||||
static char tip[50];
|
||||
static char hexcol[128];
|
||||
float rgb_gamma[3];
|
||||
float min, max, step, precision;
|
||||
float softmin, softmax, hardmin, hardmax, step, precision;
|
||||
float *hsv = ui_block_hsv_get(block);
|
||||
int yco;
|
||||
|
||||
@@ -2142,7 +2142,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
|
||||
/* sneaky way to check for alpha */
|
||||
rgba[3] = FLT_MAX;
|
||||
|
||||
RNA_property_float_ui_range(ptr, prop, &min, &max, &step, &precision);
|
||||
RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
|
||||
RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
|
||||
RNA_property_float_get_array(ptr, prop, rgba);
|
||||
|
||||
switch (U.color_picker_type) {
|
||||
@@ -2196,7 +2197,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
|
||||
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
|
||||
bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
|
||||
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
|
||||
bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
|
||||
bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
|
||||
bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
|
||||
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
|
||||
@@ -3020,16 +3020,16 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title,
|
||||
/* recurse for nested properties */
|
||||
if (RNA_property_type(prop) == PROP_POINTER) {
|
||||
PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
|
||||
const char *name = RNA_property_ui_name(prop);
|
||||
|
||||
if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
|
||||
const char *name = RNA_property_ui_name(prop);
|
||||
template_keymap_item_properties(layout, name, &propptr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* add property */
|
||||
uiItemR(flow, ptr, RNA_property_identifier(prop), 0, NULL, ICON_NONE);
|
||||
uiItemFullR(flow, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
}
|
||||
|
||||
@@ -95,9 +95,11 @@ void paintface_flush_flags(Object *ob)
|
||||
|
||||
/* loop over tessfaces */
|
||||
for (i = 0; i < totface; i++) {
|
||||
/* Copy flags onto the original tessface from its original poly */
|
||||
mp_orig = me->mpoly + index_array[i];
|
||||
faces[i].flag = mp_orig->flag;
|
||||
if (index_array[i] != ORIGINDEX_NONE) {
|
||||
/* Copy flags onto the original tessface from its original poly */
|
||||
mp_orig = me->mpoly + index_array[i];
|
||||
faces[i].flag = mp_orig->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,9 +109,11 @@ void paintface_flush_flags(Object *ob)
|
||||
|
||||
/* loop over final derived polys */
|
||||
for (i = 0; i < totpoly; i++) {
|
||||
/* Copy flags onto the final derived poly from the original mesh poly */
|
||||
mp_orig = me->mpoly + index_array[i];
|
||||
polys[i].flag = mp_orig->flag;
|
||||
if (index_array[i] != ORIGINDEX_NONE) {
|
||||
/* Copy flags onto the final derived poly from the original mesh poly */
|
||||
mp_orig = me->mpoly + index_array[i];
|
||||
polys[i].flag = mp_orig->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,9 +124,11 @@ void paintface_flush_flags(Object *ob)
|
||||
|
||||
/* loop over tessfaces */
|
||||
for (i = 0; i < totface; i++) {
|
||||
/* Copy flags onto the final tessface from its final poly */
|
||||
mp_orig = polys + index_array[i];
|
||||
faces[i].flag = mp_orig->flag;
|
||||
if (index_array[i] != ORIGINDEX_NONE) {
|
||||
/* Copy flags onto the final tessface from its final poly */
|
||||
mp_orig = polys + index_array[i];
|
||||
faces[i].flag = mp_orig->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4007,8 +4007,9 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* grr, need to return finished so the user can select different options */
|
||||
//return OPERATOR_CANCELLED;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
EDBM_update_generic(em, true, true);
|
||||
|
||||
@@ -3000,7 +3000,7 @@ static int vertex_group_vert_select_unlocked_poll(bContext *C)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ob->actdef != -1) {
|
||||
if (ob->actdef != 0) {
|
||||
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
|
||||
if (dg) {
|
||||
return !(dg->flag & DG_LOCK_WEIGHT);
|
||||
|
||||
@@ -83,7 +83,7 @@ void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot);
|
||||
|
||||
/* render_internal.c */
|
||||
void RENDER_OT_render(struct wmOperatorType *ot);
|
||||
void render_view3d(struct RenderEngine *engine, const struct bContext *C);
|
||||
void render_view3d_update(struct RenderEngine *engine, const struct bContext *C);
|
||||
void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C);
|
||||
|
||||
/* render_opengl.c uses this */
|
||||
|
||||
@@ -759,11 +759,13 @@ void RENDER_OT_render(wmOperatorType *ot)
|
||||
#define PR_UPDATE_VIEW 1
|
||||
#define PR_UPDATE_RENDERSIZE 2
|
||||
#define PR_UPDATE_MATERIAL 4
|
||||
#define PR_UPDATE_DATABASE 8
|
||||
|
||||
typedef struct RenderPreview {
|
||||
/* from wmJob */
|
||||
void *owner;
|
||||
short *stop, *do_update;
|
||||
wmJob *job;
|
||||
|
||||
Scene *scene;
|
||||
ScrArea *sa;
|
||||
@@ -774,8 +776,6 @@ typedef struct RenderPreview {
|
||||
RenderEngine *engine;
|
||||
|
||||
float viewmat[4][4];
|
||||
|
||||
int keep_data;
|
||||
} RenderPreview;
|
||||
|
||||
static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect)
|
||||
@@ -876,7 +876,13 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
|
||||
float clipsta, clipend, pixsize;
|
||||
bool orth, restore = 0;
|
||||
char name[32];
|
||||
|
||||
int update_flag;
|
||||
|
||||
update_flag = rp->engine->job_update_flag;
|
||||
rp->engine->job_update_flag = 0;
|
||||
|
||||
//printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE);
|
||||
|
||||
G.is_break = FALSE;
|
||||
|
||||
if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth))
|
||||
@@ -891,13 +897,6 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
|
||||
sprintf(name, "View3dPreview %p", (void *)rp->ar);
|
||||
re = rp->engine->re = RE_GetRender(name);
|
||||
|
||||
if (rp->engine->re == NULL) {
|
||||
|
||||
re = rp->engine->re = RE_NewRender(name);
|
||||
|
||||
rp->keep_data = 0;
|
||||
}
|
||||
|
||||
/* set this always, rp is different for each job */
|
||||
RE_test_break_cb(re, rp, render_view3d_break);
|
||||
RE_display_draw_cb(re, rp, render_view3d_draw_update);
|
||||
@@ -905,7 +904,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
|
||||
|
||||
rstats = RE_GetStats(re);
|
||||
|
||||
if (rp->keep_data == 0 || rstats->convertdone == 0 || (rp->keep_data & PR_UPDATE_RENDERSIZE)) {
|
||||
if ((update_flag & (PR_UPDATE_RENDERSIZE|PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
|
||||
/* no osa, blur, seq, layers, etc for preview render */
|
||||
rdata = rp->scene->r;
|
||||
rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
|
||||
@@ -931,11 +930,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
|
||||
|
||||
RE_SetPixelSize(re, pixsize);
|
||||
|
||||
/* database free can crash on a empty Render... */
|
||||
if (rp->keep_data == 0 && rstats->convertdone)
|
||||
RE_Database_Free(re);
|
||||
|
||||
if (rstats->convertdone == 0) {
|
||||
if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) {
|
||||
unsigned int lay = rp->scene->lay;
|
||||
|
||||
/* allow localview render for objects with lights in normal layers */
|
||||
@@ -944,8 +939,20 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
|
||||
else lay = rp->v3d->lay;
|
||||
|
||||
RE_SetView(re, rp->viewmat);
|
||||
|
||||
|
||||
/* copying blender data while main thread is locked, to avoid crashes */
|
||||
WM_job_main_thread_lock_acquire(rp->job);
|
||||
RE_Database_Free(re);
|
||||
RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view
|
||||
WM_job_main_thread_lock_release(rp->job);
|
||||
|
||||
/* do preprocessing like building raytree, shadows, volumes, SSS */
|
||||
RE_Database_Preprocess(re);
|
||||
|
||||
/* conversion not completed, need to do it again */
|
||||
if (!rstats->convertdone)
|
||||
rp->engine->job_update_flag |= PR_UPDATE_DATABASE;
|
||||
|
||||
// printf("dbase update\n");
|
||||
}
|
||||
else {
|
||||
@@ -963,8 +970,6 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
|
||||
/* always rotate back */
|
||||
if (restore)
|
||||
RE_DataBase_IncrementalView(re, rp->viewmat, 1);
|
||||
|
||||
rp->engine->flag &= ~RE_ENGINE_DO_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -975,21 +980,99 @@ static void render_view3d_free(void *customdata)
|
||||
MEM_freeN(rp);
|
||||
}
|
||||
|
||||
static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_data)
|
||||
static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C)
|
||||
{
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Render *re;
|
||||
rctf viewplane;
|
||||
rcti disprect;
|
||||
float clipsta, clipend;
|
||||
bool orth;
|
||||
int job_update_flag = 0;
|
||||
char name[32];
|
||||
|
||||
/* ensure render engine exists */
|
||||
re = engine->re;
|
||||
|
||||
if (!re) {
|
||||
sprintf(name, "View3dPreview %p", (void *)ar);
|
||||
re = engine->re = RE_GetRender(name);
|
||||
if (!re)
|
||||
re = engine->re = RE_NewRender(name);
|
||||
|
||||
engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
|
||||
}
|
||||
|
||||
/* check update_flag */
|
||||
if (engine->update_flag & RE_ENGINE_UPDATE_MA)
|
||||
job_update_flag |= PR_UPDATE_MATERIAL;
|
||||
|
||||
if (engine->update_flag & RE_ENGINE_UPDATE_OTHER)
|
||||
job_update_flag |= PR_UPDATE_MATERIAL;
|
||||
|
||||
if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) {
|
||||
job_update_flag |= PR_UPDATE_DATABASE;
|
||||
|
||||
/* load editmesh */
|
||||
if (scene->obedit)
|
||||
ED_object_editmode_load(scene->obedit);
|
||||
}
|
||||
|
||||
engine->update_flag = 0;
|
||||
|
||||
/* check if viewport changed */
|
||||
if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) {
|
||||
engine->last_winx = ar->winx;
|
||||
engine->last_winy = ar->winy;
|
||||
job_update_flag |= PR_UPDATE_RENDERSIZE;
|
||||
}
|
||||
|
||||
if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) {
|
||||
copy_m4_m4(engine->last_viewmat, rv3d->viewmat);
|
||||
job_update_flag |= PR_UPDATE_VIEW;
|
||||
}
|
||||
|
||||
render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth);
|
||||
|
||||
if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) {
|
||||
engine->last_viewplane = viewplane;
|
||||
job_update_flag |= PR_UPDATE_VIEW;
|
||||
}
|
||||
|
||||
render_view3d_disprect(scene, ar, v3d, rv3d, &disprect);
|
||||
if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) {
|
||||
engine->last_disprect = disprect;
|
||||
job_update_flag |= PR_UPDATE_RENDERSIZE;
|
||||
}
|
||||
|
||||
/* any changes? go ahead and rerender */
|
||||
if (job_update_flag) {
|
||||
engine->job_update_flag |= job_update_flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void render_view3d_do(RenderEngine *engine, const bContext *C)
|
||||
{
|
||||
wmJob *wm_job;
|
||||
RenderPreview *rp;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
if (CTX_wm_window(C) == NULL) {
|
||||
engine->flag |= RE_ENGINE_DO_UPDATE;
|
||||
if (CTX_wm_window(C) == NULL)
|
||||
return;
|
||||
if (!render_view3d_flag_changed(engine, C))
|
||||
return;
|
||||
}
|
||||
|
||||
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview",
|
||||
WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
|
||||
rp = MEM_callocN(sizeof(RenderPreview), "render preview");
|
||||
|
||||
rp->job = wm_job;
|
||||
|
||||
/* customdata for preview thread */
|
||||
rp->scene = scene;
|
||||
rp->engine = engine;
|
||||
@@ -998,7 +1081,6 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_d
|
||||
rp->v3d = rp->sa->spacedata.first;
|
||||
rp->rv3d = CTX_wm_region_view3d(C);
|
||||
rp->bmain = CTX_data_main(C);
|
||||
rp->keep_data = keep_data;
|
||||
copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
|
||||
|
||||
/* dont alloc in threads */
|
||||
@@ -1013,80 +1095,33 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_d
|
||||
WM_jobs_start(CTX_wm_manager(C), wm_job);
|
||||
|
||||
engine->flag &= ~RE_ENGINE_DO_UPDATE;
|
||||
|
||||
}
|
||||
|
||||
/* callback for render engine , on changes */
|
||||
void render_view3d(RenderEngine *engine, const bContext *C)
|
||||
void render_view3d_update(RenderEngine *engine, const bContext *C)
|
||||
{
|
||||
render_view3d_do(engine, C, 0);
|
||||
}
|
||||
/* this shouldn't be needed and causes too many database rebuilds, but we
|
||||
* aren't actually tracking updates for all relevent datablocks so this is
|
||||
* a catch-all for updates */
|
||||
engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
|
||||
|
||||
static int render_view3d_changed(RenderEngine *engine, const bContext *C)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Render *re;
|
||||
int update = 0;
|
||||
char name[32];
|
||||
|
||||
sprintf(name, "View3dPreview %p", (void *)ar);
|
||||
re = RE_GetRender(name);
|
||||
|
||||
if (re) {
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
rctf viewplane, viewplane1;
|
||||
rcti disprect, disprect1;
|
||||
float mat[4][4];
|
||||
float clipsta, clipend;
|
||||
bool orth;
|
||||
|
||||
if (engine->update_flag & RE_ENGINE_UPDATE_MA)
|
||||
update |= PR_UPDATE_MATERIAL;
|
||||
|
||||
if (engine->update_flag & RE_ENGINE_UPDATE_OTHER)
|
||||
update |= PR_UPDATE_MATERIAL;
|
||||
|
||||
engine->update_flag = 0;
|
||||
|
||||
if (engine->resolution_x != ar->winx || engine->resolution_y != ar->winy)
|
||||
update |= PR_UPDATE_RENDERSIZE;
|
||||
|
||||
RE_GetView(re, mat);
|
||||
if (compare_m4m4(mat, rv3d->viewmat, 0.00001f) == 0) {
|
||||
update |= PR_UPDATE_VIEW;
|
||||
}
|
||||
|
||||
render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth);
|
||||
RE_GetViewPlane(re, &viewplane1, &disprect1);
|
||||
|
||||
if (BLI_rctf_compare(&viewplane, &viewplane1, 0.00001f) == 0)
|
||||
update |= PR_UPDATE_VIEW;
|
||||
|
||||
render_view3d_disprect(scene, ar, v3d, rv3d, &disprect);
|
||||
if (BLI_rcti_compare(&disprect, &disprect1) == 0)
|
||||
update |= PR_UPDATE_RENDERSIZE;
|
||||
|
||||
if (update)
|
||||
engine->flag |= RE_ENGINE_DO_UPDATE;
|
||||
//if (update)
|
||||
// printf("changed ma %d res %d view %d\n", update & PR_UPDATE_MATERIAL, update & PR_UPDATE_RENDERSIZE, update & PR_UPDATE_VIEW);
|
||||
}
|
||||
|
||||
return update;
|
||||
render_view3d_do(engine, C);
|
||||
}
|
||||
|
||||
void render_view3d_draw(RenderEngine *engine, const bContext *C)
|
||||
{
|
||||
Render *re = engine->re;
|
||||
RenderResult rres;
|
||||
int keep_data = render_view3d_changed(engine, C);
|
||||
char name[32];
|
||||
|
||||
if (engine->flag & RE_ENGINE_DO_UPDATE)
|
||||
render_view3d_do(engine, C, keep_data);
|
||||
|
||||
if (re == NULL) return;
|
||||
render_view3d_do(engine, C);
|
||||
|
||||
if (re == NULL) {
|
||||
sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C));
|
||||
re = RE_GetRender(name);
|
||||
|
||||
if (re == NULL) return;
|
||||
}
|
||||
|
||||
RE_AcquireResultImage(re, &rres);
|
||||
|
||||
@@ -1136,3 +1171,52 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
|
||||
|
||||
RE_ReleaseResultImage(re);
|
||||
}
|
||||
|
||||
void ED_viewport_render_kill_jobs(const bContext *C)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
bScreen *sc;
|
||||
ScrArea *sa;
|
||||
ARegion *ar;
|
||||
|
||||
if (!wm)
|
||||
return;
|
||||
|
||||
/* kill all actively running jobs */
|
||||
WM_jobs_kill(wm, NULL, render_view3d_startjob);
|
||||
|
||||
/* loop over 3D view render engines */
|
||||
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
|
||||
for (sa = sc->areabase.first; sa; sa = sa->next) {
|
||||
if (sa->spacetype != SPACE_VIEW3D)
|
||||
continue;
|
||||
|
||||
for (ar = sa->regionbase.first; ar; ar = ar->next) {
|
||||
RegionView3D *rv3d;
|
||||
|
||||
if (ar->regiontype != RGN_TYPE_WINDOW)
|
||||
continue;
|
||||
|
||||
rv3d = ar->regiondata;
|
||||
|
||||
if (rv3d->render_engine) {
|
||||
/* free render database now before we change data, because
|
||||
* RE_Database_Free will also loop over blender data */
|
||||
char name[32];
|
||||
Render *re;
|
||||
|
||||
sprintf(name, "View3dPreview %p", (void *)ar);
|
||||
re = RE_GetRender(name);
|
||||
|
||||
if (re)
|
||||
RE_Database_Free(re);
|
||||
|
||||
/* tag render engine to update entire database */
|
||||
rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -539,7 +539,7 @@ void ED_render_internal_init(void)
|
||||
{
|
||||
RenderEngineType *ret = RE_engines_find("BLENDER_RENDER");
|
||||
|
||||
ret->view_update = render_view3d;
|
||||
ret->view_update = render_view3d_update;
|
||||
ret->view_draw = render_view3d_draw;
|
||||
|
||||
}
|
||||
|
||||
@@ -908,11 +908,19 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar)
|
||||
/* overlapping regions only in the following restricted cases */
|
||||
static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar)
|
||||
{
|
||||
if (U.uiflag2 & USER_REGION_OVERLAP)
|
||||
if (WM_is_draw_triple(win))
|
||||
if (ELEM4(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP))
|
||||
if (U.uiflag2 & USER_REGION_OVERLAP) {
|
||||
if (WM_is_draw_triple(win)) {
|
||||
if (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ)) {
|
||||
if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS))
|
||||
return 1;
|
||||
}
|
||||
else if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
|
||||
if (ELEM4(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS, RGN_TYPE_PREVIEW))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +245,8 @@ typedef struct ProjPaintState {
|
||||
float normal_angle_inner;
|
||||
float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
|
||||
|
||||
short is_ortho;
|
||||
bool do_face_sel; /* quick access to (me->editflag & ME_EDIT_PAINT_FACE_SEL) */
|
||||
bool is_ortho;
|
||||
bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
|
||||
bool is_texbrush; /* only to avoid running */
|
||||
bool is_maskbrush; /* mask brush is applied before masking */
|
||||
@@ -2809,22 +2810,28 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
Image *tpage_last = NULL, *tpage;
|
||||
|
||||
/* Face vars */
|
||||
MPoly *mpoly_orig;
|
||||
MFace *mf;
|
||||
MTFace *tf;
|
||||
|
||||
int a, i; /* generic looping vars */
|
||||
int image_index = -1, face_index;
|
||||
int *mpoly_origindex;
|
||||
MVert *mv;
|
||||
|
||||
MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
|
||||
|
||||
const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
|
||||
|
||||
bool reset_threads = false;
|
||||
|
||||
/* ---- end defines ---- */
|
||||
|
||||
if (ps->source == PROJ_SRC_VIEW)
|
||||
ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
|
||||
|
||||
ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0);
|
||||
|
||||
/* paint onto the derived mesh */
|
||||
|
||||
/* Workaround for subsurf selection, try the display mesh first */
|
||||
@@ -2833,12 +2840,17 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
|
||||
ps->dm_release = TRUE;
|
||||
}
|
||||
else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
|
||||
else if (ps->ob->derivedFinal &&
|
||||
CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) &&
|
||||
(ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX)))
|
||||
{
|
||||
ps->dm = ps->ob->derivedFinal;
|
||||
ps->dm_release = FALSE;
|
||||
}
|
||||
else {
|
||||
ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
|
||||
ps->dm = mesh_get_derived_final(
|
||||
ps->scene, ps->ob,
|
||||
ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
|
||||
ps->dm_release = TRUE;
|
||||
}
|
||||
|
||||
@@ -2858,6 +2870,15 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
|
||||
ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
|
||||
|
||||
if (ps->do_face_sel) {
|
||||
mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
|
||||
mpoly_origindex = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
|
||||
}
|
||||
else {
|
||||
mpoly_orig = NULL;
|
||||
mpoly_origindex = NULL;
|
||||
}
|
||||
|
||||
/* use clone mtface? */
|
||||
|
||||
|
||||
@@ -3064,6 +3085,10 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
|
||||
/* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
|
||||
|
||||
if (ps->buckets_x > PROJ_BUCKET_RECT_MAX || ps->buckets_y > PROJ_BUCKET_RECT_MAX) {
|
||||
reset_threads = true;
|
||||
}
|
||||
|
||||
/* really high values could cause problems since it has to allocate a few
|
||||
* (ps->buckets_x*ps->buckets_y) sized arrays */
|
||||
CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
|
||||
@@ -3089,6 +3114,11 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
|
||||
ps->thread_tot = BKE_scene_num_threads(ps->scene);
|
||||
|
||||
/* workaround for #35057, disable threading if diameter is less than is possible for
|
||||
* optimum bucket number generation */
|
||||
if (reset_threads)
|
||||
ps->thread_tot = 1;
|
||||
|
||||
for (a = 0; a < ps->thread_tot; a++) {
|
||||
ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena");
|
||||
}
|
||||
@@ -3118,8 +3148,8 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
|
||||
bool is_face_sel;
|
||||
|
||||
#ifndef PROJ_DEBUG_NOSEAMBLEED
|
||||
/* add face user if we have bleed enabled, set the UV seam flags later */
|
||||
@@ -3134,10 +3164,21 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
}
|
||||
#endif
|
||||
|
||||
tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
|
||||
|
||||
if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
|
||||
if (ps->do_face_sel) {
|
||||
int orig_index;
|
||||
if (mpoly_origindex && ((orig_index = mpoly_origindex[face_index])) != ORIGINDEX_NONE) {
|
||||
MPoly *mp = mpoly_orig + orig_index;
|
||||
is_face_sel = ((mp->flag & ME_FACE_SEL) != 0);
|
||||
}
|
||||
else {
|
||||
is_face_sel = ((mf->flag & ME_FACE_SEL) != 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
is_face_sel = true;
|
||||
}
|
||||
|
||||
if (is_face_sel && (tpage = project_paint_face_image(ps, ps->dm_mtface, face_index))) {
|
||||
float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
|
||||
|
||||
v1coSS = ps->screenCoords[mf->v1];
|
||||
|
||||
@@ -577,9 +577,10 @@ void snode_set_context(const bContext *C)
|
||||
if (!treetype ||
|
||||
(treetype->poll && !treetype->poll(C, treetype)))
|
||||
{
|
||||
/* invalid tree type, disable */
|
||||
snode->tree_idname[0] = '\0';
|
||||
ED_node_tree_start(snode, NULL, NULL, NULL);
|
||||
/* invalid tree type, skip
|
||||
* NB: not resetting the node path here, invalid bNodeTreeType
|
||||
* may still be registered at a later point.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_node.h"
|
||||
|
||||
@@ -83,6 +84,8 @@ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from)
|
||||
BLI_strncpy(path->node_name, id->name + 2, sizeof(path->node_name));
|
||||
|
||||
BLI_addtail(&snode->treepath, path);
|
||||
|
||||
id_us_ensure_real(&ntree->id);
|
||||
}
|
||||
|
||||
/* update current tree */
|
||||
@@ -116,6 +119,8 @@ void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode)
|
||||
|
||||
BLI_addtail(&snode->treepath, path);
|
||||
|
||||
id_us_ensure_real(&ntree->id);
|
||||
|
||||
/* update current tree */
|
||||
snode->edittree = ntree;
|
||||
|
||||
|
||||
@@ -3273,7 +3273,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
|
||||
Object *ob = base->object;
|
||||
Mesh *me = ob->data;
|
||||
Material *ma = give_current_material(ob, 1);
|
||||
const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO));
|
||||
const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
|
||||
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
|
||||
int /* totvert,*/ totedge, totface;
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "ED_mball.h"
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_render.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_sculpt.h"
|
||||
#include "ED_util.h"
|
||||
@@ -140,9 +141,12 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
|
||||
|
||||
if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
|
||||
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname)
|
||||
if (U.uiflag & USER_GLOBALUNDO)
|
||||
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) {
|
||||
if (U.uiflag & USER_GLOBALUNDO) {
|
||||
ED_viewport_render_kill_jobs(C);
|
||||
BKE_undo_name(C, undoname);
|
||||
}
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -192,6 +196,8 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
|
||||
/* for example, texface stores image pointers */
|
||||
undo_editmode_clear();
|
||||
|
||||
ED_viewport_render_kill_jobs(C);
|
||||
|
||||
if (undoname)
|
||||
BKE_undo_name(C, undoname);
|
||||
else
|
||||
@@ -363,6 +369,8 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
|
||||
{
|
||||
int retval;
|
||||
|
||||
ED_viewport_render_kill_jobs(C);
|
||||
|
||||
if (G.debug & G_DEBUG)
|
||||
printf("redo_cb: operator redo %s\n", op->type->name);
|
||||
ED_undo_pop_op(C, op);
|
||||
@@ -529,6 +537,7 @@ static int undo_history_exec(bContext *C, wmOperator *op)
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
|
||||
}
|
||||
else {
|
||||
ED_viewport_render_kill_jobs(C);
|
||||
BKE_undo_number(C, item);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
|
||||
}
|
||||
|
||||
@@ -211,6 +211,10 @@ typedef struct Curve {
|
||||
void *lastsel;
|
||||
|
||||
/* font part */
|
||||
/* WARNING: cu->len is...
|
||||
* - strlen(cu->str) object-mode (bytes).
|
||||
* - BLI_strlen_utf8(cu->str) in edit-mode.
|
||||
* This should be cleaned up and some point, see 'write_curves' - campbell */
|
||||
short len, lines, pos, spacemode;
|
||||
float spacing, linedist, shear, fsize, wordspace, ulpos, ulheight;
|
||||
float xof, yof;
|
||||
|
||||
@@ -6385,6 +6385,15 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool i
|
||||
return equals;
|
||||
}
|
||||
|
||||
case PROP_POINTER:
|
||||
{
|
||||
if (!STREQ(RNA_property_identifier(prop), "rna_type")) {
|
||||
PointerRNA propptr_a = RNA_property_pointer_get(a, prop);
|
||||
PointerRNA propptr_b = RNA_property_pointer_get(b, prop);
|
||||
return RNA_struct_equals(&propptr_a, &propptr_b, is_strict);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1531,7 +1531,7 @@ void IDP_spit(IDProperty *prop)
|
||||
ret_str = PyObject_Repr(ret_dict);
|
||||
Py_DECREF(ret_dict);
|
||||
|
||||
printf("IDProperty: %s\n", _PyUnicode_AsString(ret_str));
|
||||
printf("IDProperty(%p): %s\n", prop, _PyUnicode_AsString(ret_str));
|
||||
|
||||
Py_DECREF(ret_str);
|
||||
|
||||
|
||||
12
source/blender/render/extern/include/RE_engine.h
vendored
12
source/blender/render/extern/include/RE_engine.h
vendored
@@ -70,6 +70,7 @@ struct Scene;
|
||||
/* RenderEngine.update_flag, used by internal now */
|
||||
#define RE_ENGINE_UPDATE_MA 1
|
||||
#define RE_ENGINE_UPDATE_OTHER 2
|
||||
#define RE_ENGINE_UPDATE_DATABASE 4
|
||||
|
||||
extern ListBase R_engines;
|
||||
|
||||
@@ -97,7 +98,7 @@ typedef struct RenderEngine {
|
||||
RenderEngineType *type;
|
||||
void *py_instance;
|
||||
|
||||
int flag, update_flag;
|
||||
int flag;
|
||||
struct Object *camera_override;
|
||||
|
||||
int tile_x;
|
||||
@@ -110,6 +111,15 @@ typedef struct RenderEngine {
|
||||
int resolution_x, resolution_y;
|
||||
|
||||
struct ReportList *reports;
|
||||
|
||||
/* for blender internal only */
|
||||
int update_flag;
|
||||
int job_update_flag;
|
||||
|
||||
rctf last_viewplane;
|
||||
rcti last_disprect;
|
||||
float last_viewmat[4][4];
|
||||
int last_winx, last_winy;
|
||||
} RenderEngine;
|
||||
|
||||
RenderEngine *RE_engine_create(RenderEngineType *type);
|
||||
|
||||
@@ -207,6 +207,7 @@ void RE_GetViewPlane(struct Render *re, rctf *viewplane, rcti *disprect);
|
||||
|
||||
/* make or free the dbase */
|
||||
void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view);
|
||||
void RE_Database_Preprocess(struct Render *re);
|
||||
void RE_Database_Free(struct Render *re);
|
||||
|
||||
/* project dbase again, when viewplane/perspective changed */
|
||||
|
||||
@@ -4863,7 +4863,11 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject
|
||||
void RE_Database_Free(Render *re)
|
||||
{
|
||||
LampRen *lar;
|
||||
|
||||
|
||||
/* will crash if we try to free empty database */
|
||||
if (!re->i.convertdone)
|
||||
return;
|
||||
|
||||
/* statistics for debugging render memory usage */
|
||||
if ((G.debug & G_DEBUG) && (G.is_rendering)) {
|
||||
if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
|
||||
@@ -5321,14 +5325,10 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
|
||||
database_init_objects(re, lay, 0, 0, 0, 0);
|
||||
|
||||
if (!re->test_break(re->tbh)) {
|
||||
int tothalo;
|
||||
|
||||
set_material_lightgroups(re);
|
||||
for (sce= re->scene; sce; sce= sce->set)
|
||||
set_renderlayer_lightgroups(re, sce);
|
||||
|
||||
slurph_opt= 1;
|
||||
|
||||
/* for now some clumsy copying still */
|
||||
re->i.totvert= re->totvert;
|
||||
re->i.totface= re->totvlak;
|
||||
@@ -5336,7 +5336,16 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
|
||||
re->i.tothalo= re->tothalo;
|
||||
re->i.totlamp= re->totlamp;
|
||||
re->stats_draw(re->sdh, &re->i);
|
||||
|
||||
}
|
||||
|
||||
slurph_opt= 1;
|
||||
}
|
||||
|
||||
void RE_Database_Preprocess(Render *re)
|
||||
{
|
||||
if (!re->test_break(re->tbh)) {
|
||||
int tothalo;
|
||||
|
||||
/* don't sort stars */
|
||||
tothalo= re->tothalo;
|
||||
if (!re->test_break(re->tbh)) {
|
||||
@@ -5392,11 +5401,12 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
|
||||
if (!re->test_break(re->tbh))
|
||||
if (re->r.mode & R_RAYTRACE)
|
||||
volume_precache(re);
|
||||
|
||||
}
|
||||
|
||||
if (re->test_break(re->tbh))
|
||||
if (re->test_break(re->tbh)) {
|
||||
re->i.convertdone = TRUE;
|
||||
RE_Database_Free(re);
|
||||
}
|
||||
else
|
||||
re->i.convertdone = TRUE;
|
||||
|
||||
@@ -5866,8 +5876,10 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
|
||||
RE_Database_Free(re);
|
||||
re->strandsurface= strandsurface;
|
||||
|
||||
if (!re->test_break(re->tbh))
|
||||
if (!re->test_break(re->tbh)) {
|
||||
RE_Database_FromScene(re, bmain, sce, lay, 1);
|
||||
RE_Database_Preprocess(re);
|
||||
}
|
||||
|
||||
if (!re->test_break(re->tbh)) {
|
||||
int vectorlay= get_vector_renderlayers(re->scene);
|
||||
|
||||
@@ -1142,10 +1142,13 @@ static void do_render_3d(Render *re)
|
||||
re->draw_lock(re->dlh, 1);
|
||||
|
||||
/* make render verts/faces/halos/lamps */
|
||||
if (render_scene_needs_vector(re))
|
||||
if (render_scene_needs_vector(re)) {
|
||||
RE_Database_FromScene_Vectors(re, re->main, re->scene, re->lay);
|
||||
else
|
||||
}
|
||||
else {
|
||||
RE_Database_FromScene(re, re->main, re->scene, re->lay, 1);
|
||||
RE_Database_Preprocess(re);
|
||||
}
|
||||
|
||||
/* clear UI drawing locks */
|
||||
if (re->draw_lock)
|
||||
|
||||
@@ -404,6 +404,9 @@ void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type);
|
||||
|
||||
int WM_jobs_has_running(struct wmWindowManager *wm);
|
||||
|
||||
void WM_job_main_thread_lock_acquire(struct wmJob *job);
|
||||
void WM_job_main_thread_lock_release(struct wmJob *job);
|
||||
|
||||
/* clipboard */
|
||||
char *WM_clipboard_text_get(int selection);
|
||||
void WM_clipboard_text_set(char *buf, int selection);
|
||||
|
||||
@@ -128,8 +128,43 @@ struct wmJob {
|
||||
ListBase threads;
|
||||
|
||||
double start_time;
|
||||
|
||||
/* ticket mutex for main thread locking while some job accesses
|
||||
* data that the main thread might modify at the same time */
|
||||
TicketMutex *main_thread_mutex;
|
||||
bool main_thread_mutex_ending;
|
||||
};
|
||||
|
||||
/* Main thread locking */
|
||||
|
||||
void WM_job_main_thread_lock_acquire(wmJob *wm_job)
|
||||
{
|
||||
BLI_ticket_mutex_lock(wm_job->main_thread_mutex);
|
||||
|
||||
/* if BLI_end_threads is being called to stop the job before it's finished,
|
||||
* we no longer need to lock to get access to the main thread as it's
|
||||
* waiting and can't respond */
|
||||
if (wm_job->main_thread_mutex_ending)
|
||||
BLI_ticket_mutex_unlock(wm_job->main_thread_mutex);
|
||||
}
|
||||
|
||||
void WM_job_main_thread_lock_release(wmJob *wm_job)
|
||||
{
|
||||
if (!wm_job->main_thread_mutex_ending)
|
||||
BLI_ticket_mutex_unlock(wm_job->main_thread_mutex);
|
||||
}
|
||||
|
||||
static void wm_job_main_thread_yield(wmJob *wm_job, bool ending)
|
||||
{
|
||||
if (ending)
|
||||
wm_job->main_thread_mutex_ending = true;
|
||||
|
||||
/* unlock and lock the ticket mutex. because it's a fair mutex any job that
|
||||
* is waiting to acquire the lock will get it first, before we can lock */
|
||||
BLI_ticket_mutex_unlock(wm_job->main_thread_mutex);
|
||||
BLI_ticket_mutex_lock(wm_job->main_thread_mutex);
|
||||
}
|
||||
|
||||
/* finds:
|
||||
* if type, compare for it, otherwise any matching job
|
||||
*/
|
||||
@@ -162,13 +197,16 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *
|
||||
|
||||
if (wm_job == NULL) {
|
||||
wm_job = MEM_callocN(sizeof(wmJob), "new job");
|
||||
|
||||
|
||||
BLI_addtail(&wm->jobs, wm_job);
|
||||
wm_job->win = win;
|
||||
wm_job->owner = owner;
|
||||
wm_job->flag = flag;
|
||||
wm_job->job_type = job_type;
|
||||
BLI_strncpy(wm_job->name, name, sizeof(wm_job->name));
|
||||
|
||||
wm_job->main_thread_mutex = BLI_ticket_mutex_alloc();
|
||||
BLI_ticket_mutex_lock(wm_job->main_thread_mutex);
|
||||
}
|
||||
/* else: a running job, be careful */
|
||||
|
||||
@@ -369,12 +407,21 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
|
||||
}
|
||||
}
|
||||
|
||||
static void wm_job_free(wmWindowManager *wm, wmJob *wm_job)
|
||||
{
|
||||
BLI_remlink(&wm->jobs, wm_job);
|
||||
BLI_ticket_mutex_unlock(wm_job->main_thread_mutex);
|
||||
BLI_ticket_mutex_free(wm_job->main_thread_mutex);
|
||||
MEM_freeN(wm_job);
|
||||
}
|
||||
|
||||
/* stop job, end thread, free data completely */
|
||||
static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
|
||||
{
|
||||
if (wm_job->running) {
|
||||
/* signal job to end */
|
||||
wm_job->stop = TRUE;
|
||||
wm_job_main_thread_yield(wm_job, true);
|
||||
BLI_end_threads(&wm_job->threads);
|
||||
|
||||
if (wm_job->endjob)
|
||||
@@ -389,9 +436,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
|
||||
wm_job->run_free(wm_job->run_customdata);
|
||||
|
||||
/* remove wm_job */
|
||||
BLI_remlink(&wm->jobs, wm_job);
|
||||
MEM_freeN(wm_job);
|
||||
|
||||
wm_job_free(wm, wm_job);
|
||||
}
|
||||
|
||||
/* wait until every job ended */
|
||||
@@ -483,7 +528,6 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
|
||||
float total_progress = 0.f;
|
||||
float jobs_progress = 0;
|
||||
|
||||
|
||||
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_jobnext) {
|
||||
wm_jobnext = wm_job->next;
|
||||
|
||||
@@ -491,6 +535,9 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
|
||||
|
||||
/* running threads */
|
||||
if (wm_job->threads.first) {
|
||||
|
||||
/* let threads get temporary lock over main thread if needed */
|
||||
wm_job_main_thread_yield(wm_job, false);
|
||||
|
||||
/* always call note and update when ready */
|
||||
if (wm_job->do_update || wm_job->ready) {
|
||||
@@ -522,7 +569,9 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
|
||||
}
|
||||
|
||||
wm_job->running = FALSE;
|
||||
wm_job_main_thread_yield(wm_job, true);
|
||||
BLI_end_threads(&wm_job->threads);
|
||||
wm_job->main_thread_mutex_ending = false;
|
||||
|
||||
if (wm_job->endnote)
|
||||
WM_event_add_notifier(C, wm_job->endnote, NULL);
|
||||
@@ -539,8 +588,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
|
||||
wm_job->wt = NULL;
|
||||
|
||||
/* remove wm_job */
|
||||
BLI_remlink(&wm->jobs, wm_job);
|
||||
MEM_freeN(wm_job);
|
||||
wm_job_free(wm, wm_job);
|
||||
}
|
||||
}
|
||||
else if (wm_job->flag & WM_JOB_PROGRESS) {
|
||||
|
||||
Reference in New Issue
Block a user