[Bf-blender-cvs] [acf50b21f29] soc-2019-fast-io: [Fast import/export] Review and documentation, and bug fixes

Hugo Sales noreply at git.blender.org
Thu Jun 6 15:25:43 CEST 2019


Commit: acf50b21f29b5797344cbf61cda5843df7e37173
Author: Hugo Sales
Date:   Thu Jun 6 14:25:09 2019 +0100
Branches: soc-2019-fast-io
https://developer.blender.org/rBacf50b21f29b5797344cbf61cda5843df7e37173

[Fast import/export] Review and documentation, and bug fixes

===================================================================

M	source/blender/editors/io/intern/common.hpp
M	source/blender/editors/io/intern/obj.cpp

===================================================================

diff --git a/source/blender/editors/io/intern/common.hpp b/source/blender/editors/io/intern/common.hpp
index dd8219588b9..99d22e8d86e 100644
--- a/source/blender/editors/io/intern/common.hpp
+++ b/source/blender/editors/io/intern/common.hpp
@@ -91,6 +91,9 @@ namespace common {
 	// --- TEMPLATES ---
 
 	// Adapt a pointer-size pair as a random access iterator
+	// This makes use of `boost::iterator_facade` and makes it possible to use
+	// for each style loops, as well as cleanly hiding how the underlying Blender
+	// data structures are accessed
 	template<typename SourceT, typename Tag = std::random_access_iterator_tag>
 	struct pointer_iterator :
 		public boost::iterator_facade<pointer_iterator<SourceT, Tag>, SourceT &, Tag> {
@@ -101,9 +104,9 @@ namespace common {
 		explicit pointer_iterator(SourceT *p, size_t size) : it(p), first(p), size(size) {}
 		operator SourceT *() const { return it; }
 		pointer_iterator & operator=(const pointer_iterator<SourceT, Tag> &p) {
-			this->it = p.it;
-			this->first = p.first;
-			this->size = p.size;
+			// Placement new: construct a new object in the position of `this`
+			// Doesn't actually allocate memory
+			new (this) pointer_iterator(p);
 			return *this;
 		}
 		// pointer_iterator & operator=(pointer_iterator<SourceT, Tag> &&p) = default;//  {
@@ -121,11 +124,15 @@ namespace common {
 		bool equal(const pointer_iterator &other) const { return it == other.it; }
 		SourceT & dereference() const { return *this->it; }
 		SourceT *it;
-		SourceT *first;
+		SourceT * const first;
 		size_t size;
 	};
 
-	// TODO soemeone Document CTRP
+	// This is another iterator, whcih makes use of `boost::iterator_adaptor` to change  how the underlying
+	// iterator behaves. Specifically, it uses the derived class' `dereference` method.
+	// This makes use of CRTP, the curiously recurring template pattern
+	// This means that the base class has, as a template paramater, the type of the derived class
+	// which means that it can hold a pointer to said derived class and call it's `dereference` method.
 	template<typename SourceT, typename ResT, typename CRTP,
 	         typename Base = pointer_iterator<SourceT>,
 	         typename Tag = typename std::iterator_traits<Base>::iterator_category>
@@ -145,25 +152,25 @@ namespace common {
 			: 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}; }
+		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}; }
+		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;
 	};
 
+	// Another iterator that iterates over doubly linked lists
 	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(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::iterator_adaptor_(pointer_iterator<SourceT, Tag>{first}), first(first) {}
 		list_iterator       begin()  const { return list_iterator{first}; }
 		list_iterator       end()    const { return list_iterator{nullptr}; }
 		const list_iterator cbegin() const { return list_iterator{first}; }
@@ -175,16 +182,19 @@ namespace common {
 		SourceT * const first;
 	};
 
+	// Iterator over the polygons of a mesh
 	struct poly_iter : pointer_iterator<MPoly> {
 		poly_iter(const Mesh * const m) : pointer_iterator(m->mpoly, m->totpoly) {}
 		poly_iter(const pointer_iterator &p) : pointer_iterator(p) {}
 		poly_iter(pointer_iterator &&p) : pointer_iterator(std::move(p)) {}
 	};
 
+	// Iterator over the vertices of a mesh
 	struct vert_iter : pointer_iterator<MVert> {
 		vert_iter(const Mesh * const m) : pointer_iterator(m->mvert, m->totvert) {}
 	};
 
+	// Iterator over the vertices of a polygon
 	struct vert_of_poly_iter : public dereference_iterator<MLoop, MVert &, vert_of_poly_iter> {
 		// TODO someone What order are the vertices stored in? Clockwise?
 		explicit vert_of_poly_iter(const Mesh * const mesh, const MPoly &mp)
@@ -193,6 +203,7 @@ namespace common {
 		const Mesh * const mesh;
 	};
 
+	// Iterator over the UVs of a mesh (as `const std::array<float, 2>`)
 	struct uv_iter : public dereference_iterator<MLoopUV, const std::array<float, 2>, uv_iter> {
 		explicit uv_iter(const Mesh * const m)
 			: dereference_iterator(m->mloopuv, m->totloop, this) {}
@@ -205,12 +216,14 @@ namespace common {
 		}
 	};
 
+	// Iterator over all the edges of a mesh
 	struct edge_iter : pointer_iterator<MEdge> {
 		edge_iter(const Mesh * const m) : pointer_iterator(m->medge, m->totedge) {}
 		edge_iter(const pointer_iterator<MEdge> &pi) : pointer_iterator(pi) {}
 		edge_iter(pointer_iterator<MEdge> &&pi) : pointer_iterator(pi) {}
 	};
 
+	// Iterator over the edges of a mesh whcih are marked as loose
 	struct loose_edge_iter : public boost::iterator_adaptor<loose_edge_iter, edge_iter,
 	                                                        MEdge, std::bidirectional_iterator_tag> {
 		explicit loose_edge_iter(const Mesh * const m, const edge_iter &e)
@@ -231,6 +244,7 @@ namespace common {
 		const Mesh * const mesh;
 	};
 
+	// Iterator over all the objects in a `ViewLayer`
 	// TODO someone G.is_break
 	struct object_iter : dereference_iterator<Base, Object *, object_iter, list_iterator<Base>> {
 		explicit object_iter(const ViewLayer * const vl)
@@ -238,18 +252,29 @@ namespace common {
 		inline static Object * dereference(const list_iterator<Base> &b) { return b->object; }
 	};
 
+	// Iterator over the modifiers of an `Object`
 	struct modifier_iter : list_iterator<ModifierData> {
 		explicit modifier_iter(const Object * const ob)
 			: list_iterator((ModifierData *) ob->modifiers.first) {}
 	};
 
+	// Iterator over the `MLoop` if a `MPoly` of a mesh
 	struct loop_of_poly_iter : pointer_iterator<MLoop> {
 		explicit loop_of_poly_iter(const Mesh * const mesh, const poly_iter &poly)
 			: pointer_iterator(mesh->mloop + poly->loopstart, poly->totloop - 1) {}
+		explicit loop_of_poly_iter(const Mesh * const mesh, const MPoly &poly)
+			: pointer_iterator(mesh->mloop + poly.loopstart, poly.totloop - 1) {}
 		loop_of_poly_iter(const pointer_iterator &p) : pointer_iterator(p) {}
 		loop_of_poly_iter(pointer_iterator &&p) : pointer_iterator(std::move(p)) {}
 	};
 
+	// Iterator over the normals of mesh
+	// This is a more complex one, because there are three possible sources for the normals of a mesh:
+	//   - Custom normals
+	//   - Face normals, when the face is not smooth shaded
+	//   - Vertex normals, when the face is smooth shaded
+	// This is a completely separate iterator because it needs to override pretty much all behaviours
+	// It's only a bidirectional iterator, because it is not continuous
 	struct normal_iter :
 		public boost::iterator_facade<normal_iter, std::array<float, 3>,
 		                              std::bidirectional_iterator_tag, const std::array<float, 3>> {
@@ -259,8 +284,7 @@ namespace common {
 		normal_iter(normal_iter &&) = default;
 		explicit normal_iter(const Mesh * const mesh, const poly_iter poly, const loop_of_poly_iter loop)
 			: mesh(mesh), poly(poly), loop(loop) {
-			loop_no = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
-			// ++this->loop;
+			custom_no = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
 		}
 		explicit normal_iter(const Mesh * const mesh)
 			: normal_iter(mesh, poly_iter(mesh), loop_of_poly_iter(mesh, poly_iter(mesh))) {}
@@ -268,58 +292,48 @@ namespace common {
 		normal_iter end()   const { return normal_iter(mesh, poly.end(), loop.end()); }
 		friend class boost::iterator_core_access;
 		void increment() {
-			// if (loop != loop.end()) {
-			// 	if (poly->flag & ME_SMOOTH)
-			// 		++loop;
-			// } else {
-			// 	loop = loop_of_poly_iter{mesh, poly};
-			// }
-
-			// if (poly != poly.end()) {
-			// 	++poly;
-			// 	loop = loop_of_poly_iter{mesh, poly};
-
-			// } else {
-			// 	loop = loop.end();
-			// }
-			// If not in the last of the loop and face is smooth shaded, each vertex has it's
-			// own normal, so increment loop, otherwise go to the next poly
-			//  && (loop_no != nullptr || (poly->flag & ME_SMOOTH) != 0)
+			// If we're not at the end of the loop, we increment it
 			if (loop != loop.end()) {
 				++loop;
 			} else if (poly != poly.end()) {
+				// if we're not at the end of the poly, we increment it
 				++poly;
 				if (poly != poly.end())
+					// if incrementing the poly didn't put us past the end,
+					// use the new poly to generate the new loop iterator
 					loop = loop_of_poly_iter{mesh, poly};
 			}
-			//  else {
-			// 	loop = loop.end();
-			// 	poly = poly.end();
-			// }
 		}
 		void decrement() {
-			if ((loop != loop.begin()) && ((poly->flag & ME_SMOOTH) != 0)) {
+			if (loop != loop.begin()) {
 				--loop;
 			} else if (poly != poly.begin()) {
 				--poly;
-				loop = loop_of_poly_iter(mesh, poly);
-			} else {
-				loop = loop.end();
-				poly = poly.end();
+				loop = loop_of_poly_iter{mesh, poly};
 			}
 		}
 		bool equal(const normal_iter &other) const {
-			return poly 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list