diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index 59d041580e2..00e02ca5d5d 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -774,24 +774,33 @@ void GeometryManager::device_update(Device *device, } size_t i = 0; - for (Geometry *geom : scene->geometry) { + thread_mutex status_mutex; + parallel_for_each(scene->geometry.begin(), scene->geometry.end(), [&](Geometry *geom) { + if (progress.get_cancel()) { + return; + } + if (!(geom->is_modified() && geom->is_mesh())) { - continue; + return; } Mesh *mesh = static_cast(geom); if (num_tessellation && mesh->need_tesselation()) { - string msg = "Tessellating "; - if (mesh->name.empty()) { - msg += string_printf("%u/%u", (uint)(i + 1), (uint)num_tessellation); - } - else { - msg += string_printf( - "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)num_tessellation); - } + { + const thread_scoped_lock status_lock(status_mutex); + string msg = "Tessellating "; + if (mesh->name.empty()) { + msg += string_printf("%u/%u", (uint)(i + 1), (uint)num_tessellation); + } + else { + msg += string_printf( + "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)num_tessellation); + } - progress.set_status("Updating Mesh", msg); + progress.set_status("Updating Mesh", msg); + i++; + } SubdParams subd_params(mesh); subd_params.dicing_rate = mesh->get_subd_dicing_rate(); @@ -800,8 +809,6 @@ void GeometryManager::device_update(Device *device, subd_params.camera = dicing_camera; mesh->tessellate(subd_params); - - i++; } /* Apply generated attribute if needed or remove if not needed */ @@ -811,11 +818,7 @@ void GeometryManager::device_update(Device *device, if (!mesh->has_true_displacement()) { mesh->update_tangents(scene, false); } - - if (progress.get_cancel()) { - return; - } - } + }); if (progress.get_cancel()) { return; diff --git a/intern/cycles/util/unique_ptr_vector.h b/intern/cycles/util/unique_ptr_vector.h index 812aa6c4ac3..376b64254f5 100644 --- a/intern/cycles/util/unique_ptr_vector.h +++ b/intern/cycles/util/unique_ptr_vector.h @@ -104,12 +104,23 @@ template class unique_ptr_vector { /* Basic iterators for range based for loop. */ struct ConstIterator { + using iterator_category = std::random_access_iterator_tag; + + using value_type = typename vector>::value_type; + using difference_type = typename vector>::difference_type; + using pointer = typename vector>::const_pointer; + using reference = typename vector>::reference; + typename vector>::const_iterator it; const T *operator*() const { return it->get(); } + bool operator==(const ConstIterator &other) const + { + return it == other.it; + } bool operator!=(const ConstIterator &other) const { return it != other.it; @@ -118,6 +129,21 @@ template class unique_ptr_vector { { ++it; } + difference_type operator-(const ConstIterator &other) const noexcept + { + return static_cast(it - other.it); + } + ConstIterator operator+(const difference_type offset) const noexcept + { + ConstIterator temp = *this; + temp += offset; + return temp; + } + ConstIterator &operator+=(const difference_type offset) noexcept + { + it += offset; + return *this; + } }; ConstIterator begin() const @@ -130,12 +156,23 @@ template class unique_ptr_vector { } struct Iterator { + using iterator_category = std::random_access_iterator_tag; + + using value_type = typename vector>::value_type; + using difference_type = typename vector>::difference_type; + using pointer = typename vector>::const_pointer; + using reference = typename vector>::reference; + typename vector>::const_iterator it; T *operator*() const { return it->get(); } + bool operator==(const Iterator &other) const + { + return it == other.it; + } bool operator!=(const Iterator &other) const { return it != other.it; @@ -144,6 +181,21 @@ template class unique_ptr_vector { { ++it; } + difference_type operator-(const Iterator &other) const noexcept + { + return static_cast(it - other.it); + } + Iterator operator+(const difference_type offset) const noexcept + { + Iterator temp = *this; + temp += offset; + return temp; + } + Iterator &operator+=(const difference_type offset) noexcept + { + it += offset; + return *this; + } }; Iterator begin() {