[Bf-blender-cvs] [2eb8ba7005e] soc-2019-fast-io: [Fast import/export] Initial iterator implementation and STL export
Hugo Sales
noreply at git.blender.org
Mon Jun 3 10:52:22 CEST 2019
Commit: 2eb8ba7005e1a6db5bd64e743f66a6e3a88f716e
Author: Hugo Sales
Date: Mon Jun 3 09:51:58 2019 +0100
Branches: soc-2019-fast-io
https://developer.blender.org/rB2eb8ba7005e1a6db5bd64e743f66a6e3a88f716e
[Fast import/export] Initial iterator implementation and STL export
===================================================================
M release/scripts/startup/bl_ui/space_topbar.py
M source/blender/editors/io/intern/common.cpp
M source/blender/editors/io/intern/common.hpp
M source/blender/editors/io/intern/obj.cpp
M source/blender/editors/io/intern/stl.cpp
M source/blender/editors/io/intern/stl.h
M source/blender/editors/io/io_common.c
M source/blender/editors/io/io_obj.c
M source/blender/editors/io/io_stl.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index 01a7dd0346c..33114a777fa 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -408,7 +408,8 @@ class TOPBAR_MT_file_import(Menu):
if bpy.app.build_options.alembic:
self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
- self.layout.operator("wm.obj_import", text="Wavefront (.obj)")
+ self.layout.operator("wm.obj_import_c", text="Wavefront (.obj)")
+ self.layout.operator("wm.stl_import_c", text="STL (.stl)")
class TOPBAR_MT_file_export(Menu):
@@ -421,7 +422,8 @@ class TOPBAR_MT_file_export(Menu):
if bpy.app.build_options.alembic:
self.layout.operator("wm.alembic_export", text="Alembic (.abc)")
- self.layout.operator("wm.obj_export", text="Wavefront (.obj)")
+ self.layout.operator("wm.obj_export_c", text="Wavefront (.obj)")
+ self.layout.operator("wm.stl_export_c", text="STL (.stl)")
class TOPBAR_MT_file_external_data(Menu):
bl_label = "External Data"
diff --git a/source/blender/editors/io/intern/common.cpp b/source/blender/editors/io/intern/common.cpp
index a1be9c54687..570694f3e4a 100644
--- a/source/blender/editors/io/intern/common.cpp
+++ b/source/blender/editors/io/intern/common.cpp
@@ -123,9 +123,8 @@ namespace common {
/* Temporarily disable modifiers if we shouldn't apply them */
if (!settings->apply_modifiers)
- for_each_modifier(ob, [](ModifierData *md){
- md->mode |= eModifierMode_DisableTemporary;
- });
+ for(ModifierData &md : common::modifier_iter{ob})
+ md.mode |= eModifierMode_DisableTemporary;
float scale_mat[4][4];
scale_m4_fl(scale_mat, settings->global_scale);
@@ -154,9 +153,8 @@ namespace common {
(Object *) ob, &CD_MASK_MESH);
if (!settings->apply_modifiers)
- for_each_modifier(ob, [](ModifierData *md){
- md->mode &= ~eModifierMode_DisableTemporary;
- });
+ for(ModifierData &md : common::modifier_iter{ob})
+ md.mode &= ~eModifierMode_DisableTemporary;
if (settings->triangulate) {
struct BMeshCreateParams bmcp = {false};
@@ -177,6 +175,11 @@ namespace common {
return false;
}
+ void free_mesh(Mesh *mesh, bool needs_free) {
+ if (needs_free)
+ BKE_id_free(NULL, mesh); // TODO someoene null? (alembic)
+ }
+
std::string get_object_name(const Object * const eob, const Mesh * const mesh) {
std::string name{eob->id.name + 2};
std::string mesh_name{mesh->id.name + 2};
@@ -184,6 +187,10 @@ namespace common {
return name;
}
+ std::string get_version_string() {
+ return ""; // TODO someone implement
+ }
+
void export_start(bContext *UNUSED(C), ExportSettings * const settings) {
/* From alembic_capi.cc
* XXX annoying hack: needed to prevent data corruption when changing
@@ -214,4 +221,12 @@ namespace common {
std::cout << "Took " << (std::chrono::steady_clock::now() - f).count() << "ns\n";
return ret;
}
+
+ const std::array<float, 3> calculate_normal(const Mesh * const mesh,
+ const MPoly &mp) {
+ float no[3];
+ BKE_mesh_calc_poly_normal(&mp, mesh->mloop + mp.loopstart,
+ mesh->mvert, no);
+ return std::array<float, 3>{no[0], no[1], no[2]};
+ }
}
diff --git a/source/blender/editors/io/intern/common.hpp b/source/blender/editors/io/intern/common.hpp
index 5c492b40687..3d036c75f6f 100644
--- a/source/blender/editors/io/intern/common.hpp
+++ b/source/blender/editors/io/intern/common.hpp
@@ -27,6 +27,7 @@ extern "C" {
#include "BLI_listbase.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
+#include "BLI_utildefines.h"
#include "bmesh.h"
#include "bmesh_tools.h"
@@ -50,6 +51,10 @@ extern "C" {
#include <set>
#include <array>
#include <typeinfo>
+#include <iterator>
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
namespace common {
using ulong = unsigned long;
@@ -65,117 +70,241 @@ namespace common {
void change_orientation(float (&mat)[4][4], int forward, int up);
bool get_final_mesh(const ExportSettings * const settings, const Scene * const escene,
- const Object *eob, Mesh **mesh);
+ const Object *ob, Mesh **mesh /* out */);
+
+ void free_mesh(Mesh *mesh, bool needs_free);
- std::string get_object_name(const Object * const eob, const Mesh * const mesh);
+ std::string get_object_name(const Object * const ob, const Mesh * const mesh);
+ std::string get_version_string();
void export_start(bContext *C, ExportSettings * const settings);
bool export_end(bContext *C, ExportSettings * const settings);
- // Execute `start` and `end` and time it. Those functions should be specific to each exportter,
- // but have the same signature as the two above
+ // Execute `start` and `end` and time it. Those functions should be
+ // specific to each exportter, but have the same signature as the two above
bool time_export(bContext *C, ExportSettings * const settings,
typeof(export_start) start, typeof(export_end) end);
+ const std::array<float, 3> calculate_normal(const Mesh * const mesh,
+ const MPoly &mp);
+
// --- TEMPLATES ---
- template<typename func>
- void for_each_modifier(const Object * const ob, func f) {
- for (ModifierData *md = (ModifierData *) ob->modifiers.first;
- md; md = md->next)
- f(md);
- }
+ // Adapt a pointer-size pair as a random access iterator
+ template<typename SourceT, typename Tag = std::random_access_iterator_tag>
+ struct pointer_iterator :
+ public boost::iterator_facade<pointer_iterator<SourceT, Tag>, SourceT &, Tag> {
+ pointer_iterator() = default;
+ pointer_iterator(const pointer_iterator<SourceT, Tag> &) = default;
+ pointer_iterator(pointer_iterator<SourceT, Tag> &&) = default;
+ explicit pointer_iterator(SourceT *p) : it(p), first(p), size(0) {}
+ explicit pointer_iterator(SourceT *p, size_t size) : it(p), first(p), size(size) {}
+ pointer_iterator operator=(const pointer_iterator<SourceT, Tag> &p) {
+ return pointer_iterator<SourceT, Tag>(p);
+ }
+ pointer_iterator operator=(pointer_iterator<SourceT, Tag> &&p) {
+ return pointer_iterator<SourceT, Tag>(p);
+ }
+ pointer_iterator begin() const { return pointer_iterator{first, size}; }
+ const pointer_iterator cbegin() const { return pointer_iterator{first, size}; }
+ pointer_iterator end() const { return pointer_iterator{first + size, size}; }
+ const pointer_iterator cend() const { return pointer_iterator{first + size, size}; }
+ friend class boost::iterator_core_access;
+ void increment() { ++it; }
+ void decrement() { --it; }
+ void advance(ptrdiff_t n) { it += n; }
+ ptrdiff_t distance_to(const pointer_iterator &other) { return other.it - it; }
+ bool equal(const pointer_iterator &other) const { return it == other.it; }
+ SourceT & dereference() const { return *this->it; }
+ SourceT *it;
+ SourceT * const first;
+ size_t size;
+ };
- template<typename func>
- void for_each_base(ViewLayer * const view_layer, func f) {
- for (Base *base = static_cast<Base *>(view_layer->object_bases.first);
- base; base = base->next)
- if (!G.is_break && !f(base)) // If we should break, or f return false (error)
- break;
- G.is_break = false;
- }
+ // TODO soemeone Document CTRP
+ template<typename SourceT, typename ResT, typename CRTP,
+ typename Base = pointer_iterator<SourceT>,
+ typename Tag = typename std::iterator_traits<Base>::iterator_category>
+ struct dereference_iterator
+ : public boost::iterator_adaptor<dereference_iterator<SourceT, ResT, CRTP, Base>,
+ Base, ResT, Tag, ResT> {
+ using dereference_iterator_ = dereference_iterator<SourceT, ResT, CRTP, Base>;
+ dereference_iterator() : dereference_iterator::iterator_adaptor_(), crtp(nullptr) {}
+ dereference_iterator(const dereference_iterator &di, CRTP *crtp)
+ : dereference_iterator::iterator_adaptor_(di.base()), crtp(crtp) {}
+ dereference_iterator(dereference_iterator &&di, CRTP *crtp)
+ : dereference_iterator::iterator_adaptor_(di.base()), crtp(crtp) {}
+ dereference_iterator(Base const & other, CRTP *crtp)
+ : dereference_iterator::iterator_adaptor_(other), crtp(crtp) {}
+ template<typename Size = size_t>
+ explicit dereference_iterator(SourceT *p, Size size, CRTP *crtp)
+ : dereference_iterator(Base{p, (size_t) size}, crtp) {}
+ explicit dereference_iterator(SourceT *p, CRTP *crtp) // For list_iterator
+ : dereference_iterator(Base{p}, crtp) {}
+ dereference_iterator begin() const { return {this->base().begin(), crtp}; }
+ const dereference_iterator cbegin() const { return {this->base().cbegin(), crtp}; }
+ dereference_iterator end() const { return {this->base().end(), crtp}; }
+ const dereference_iterator cend() const { return {this->base().cend(), crtp}; }
+ friend class boost::iterator_core_access;
+ ResT dereference() const { return crtp->dereference(this->base()); }
+ CRTP *crtp;
+ };
- template<typename func>
- void for_each_vertex(const Mesh * const mesh, func f) {
- // TODO someone Should this use iterators? Unsure if those are only for BMesh
- for (int i = 0, e = mesh->totvert; i < e; ++i)
- f(i, mesh->mvert[i]);
- }
+ template<typename SourceT, typename ResT = SourceT &,
+ typename Tag = std::bidirectional_iterator_tag>
+ struct list_iterator : public boost::iterator_adaptor<list_iterator<SourceT, ResT, Tag>,
+ pointer_iterator<SourceT, Tag>, ResT, Tag, ResT> {
+ list_iterator() : list_iterator::iterator_adaptor_() {}
+ list_iterator(const pointer_iterator<SourceT, Tag> & other)
+ : list_iterator::iterator_adaptor_(other), first(other.first) {}
+ explicit list_iterator(SourceT *first)
+ : list_iterator::iterator_adaptor_(pointer_iterator<SourceT, Tag>{first}),
+ first(first) {}
+ list_iterator
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list