[Bf-blender-cvs] [59080a1d] object_nodes: Implementation of a simple 'Array' modifier node.

Lukas Tönne noreply at git.blender.org
Tue Nov 24 09:44:55 CET 2015


Commit: 59080a1d81630ffbec4d5d6e7316404ba65ecf72
Author: Lukas Tönne
Date:   Sun Nov 22 15:24:07 2015 +0100
Branches: object_nodes
https://developer.blender.org/rB59080a1d81630ffbec4d5d6e7316404ba65ecf72

Implementation of a simple 'Array' modifier node.

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

M	release/scripts/startup/bl_operators/object_nodes.py
M	source/blender/blenvm/bvm/CMakeLists.txt
M	source/blender/blenvm/bvm/bvm_eval.cc
A	source/blender/blenvm/bvm/bvm_eval_mesh.h
M	source/blender/blenvm/bvm/bvm_function.h
M	source/blender/blenvm/bvm/bvm_opcode.h
M	source/blender/blenvm/compile/bvm_nodegraph.cc

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

diff --git a/release/scripts/startup/bl_operators/object_nodes.py b/release/scripts/startup/bl_operators/object_nodes.py
index 3c30368..fd822fd 100644
--- a/release/scripts/startup/bl_operators/object_nodes.py
+++ b/release/scripts/startup/bl_operators/object_nodes.py
@@ -23,6 +23,7 @@ import nodeitems_utils
 from bpy.types import Operator, ObjectNode, NodeTree, Node, NodeSocket
 from bpy.props import *
 from nodeitems_utils import NodeCategory, NodeItem
+from mathutils import *
 
 ###############################################################################
 # Socket Types
@@ -69,11 +70,14 @@ node_categories = [
         ]),
     
     GeometryNodeCategory("GEO_INPUT", "Input", items=[
-        NodeItem("GeometryMeshNode"),
+        NodeItem("GeometryMeshLoadNode"),
         ]),
     GeometryNodeCategory("GEO_OUTPUT", "Output", items=[
         NodeItem("GeometryOutputNode"),
         ]),
+    GeometryNodeCategory("GEO_MODIFIER", "Modifier", items=[
+        NodeItem("GeometryMeshArrayNode"),
+        ]),
     
     ForceFieldNodeCategory("FORCE_INPUT", "Input", items=[
         NodeItem("ForcePointDataNode"),
@@ -126,8 +130,6 @@ class NodeCompiler:
             node.set_value_float3(name, socket.default_value)
         elif isinstance(socket, bpy.types.NodeSocketColor):
             node.set_value_float4(name, socket.default_value)
-        elif isinstance(socket, bpy.types.NodeSocketColor):
-            node.set_value_float4(name, socket.default_value)
         elif isinstance(socket, bpy.types.NodeSocketInt):
             node.set_value_int(name, socket.default_value)
 
@@ -260,9 +262,9 @@ class GeometryOutputNode(GeometryNodeBase, ObjectNode):
         compiler.set_output("mesh", node, "value")
 
 
-class GeometryMeshNode(GeometryNodeBase, ObjectNode):
+class GeometryMeshLoadNode(GeometryNodeBase, ObjectNode):
     '''Mesh object data'''
-    bl_idname = 'GeometryMeshNode'
+    bl_idname = 'GeometryMeshLoadNode'
     bl_label = 'Mesh'
 
     def init(self, context):
@@ -273,6 +275,25 @@ class GeometryMeshNode(GeometryNodeBase, ObjectNode):
         compiler.map_output(0, node, "mesh")
 
 
+class GeometryMeshArrayNode(GeometryNodeBase, ObjectNode):
+    '''Make a number of transformed copies of a mesh'''
+    bl_idname = 'GeometryMeshArrayNode'
+    bl_label = 'Array'
+
+    def init(self, context):
+        self.inputs.new('GeometrySocket', "")
+        self.inputs.new('NodeSocketInt', "Count")
+        self.inputs.new('NodeSocketVector', "Offset")
+        self.outputs.new('GeometrySocket', "")
+
+    def compile(self, compiler):
+        node = compiler.add_node("MESH_ARRAY", self.name)
+        compiler.map_input(0, node, "mesh_in")
+        compiler.map_input(1, node, "count")
+        node.set_value_matrix44("transform", Matrix.Translation((0.6,0,0)))
+        compiler.map_output(0, node, "mesh_out")
+
+
 ###############################################################################
 
 
diff --git a/source/blender/blenvm/bvm/CMakeLists.txt b/source/blender/blenvm/bvm/CMakeLists.txt
index 64933aa..3294e8a 100644
--- a/source/blender/blenvm/bvm/CMakeLists.txt
+++ b/source/blender/blenvm/bvm/CMakeLists.txt
@@ -41,6 +41,7 @@ set(SRC
 	bvm_eval.cc
 	bvm_eval.h
 	bvm_eval_common.h
+	bvm_eval_mesh.h
 	bvm_eval_texture.h
 	bvm_function.cc
 	bvm_function.h
diff --git a/source/blender/blenvm/bvm/bvm_eval.cc b/source/blender/blenvm/bvm/bvm_eval.cc
index 411ff1f..a454a3b 100644
--- a/source/blender/blenvm/bvm/bvm_eval.cc
+++ b/source/blender/blenvm/bvm/bvm_eval.cc
@@ -44,6 +44,7 @@ extern "C" {
 
 #include "bvm_eval.h"
 #include "bvm_eval_common.h"
+#include "bvm_eval_mesh.h"
 #include "bvm_eval_texture.h"
 
 #include "bvm_util_math.h"
@@ -438,14 +439,6 @@ static void eval_op_effector_closest_point(float *stack, StackIndex offset_objec
 	}
 }
 
-static void eval_op_mesh_load(const EvalData *data, float *stack, StackIndex offset)
-{
-	mesh_ptr p = stack_load_mesh(stack, offset);
-	DerivedMesh *dm = CDDM_from_mesh(data->modifier.base_mesh);
-	p.set(dm);
-	stack_store_mesh(stack, offset, p);
-}
-
 void EvalContext::eval_instructions(const EvalGlobals *globals, const EvalData *data, const Function *fn, float *stack) const
 {
 	int instr = 0;
@@ -841,6 +834,14 @@ void EvalContext::eval_instructions(const EvalGlobals *globals, const EvalData *
 				eval_op_mesh_load(data, stack, offset_mesh);
 				break;
 			}
+			case OP_MESH_ARRAY: {
+				StackIndex offset_mesh_in = fn->read_stack_index(&instr);
+				StackIndex offset_count = fn->read_stack_index(&instr);
+				StackIndex offset_transform = fn->read_stack_index(&instr);
+				StackIndex offset_mesh_out = fn->read_stack_index(&instr);
+				eval_op_mesh_array(stack, offset_mesh_in, offset_mesh_out, offset_count, offset_transform);
+				break;
+			}
 			case OP_END:
 				return;
 			default:
diff --git a/source/blender/blenvm/bvm/bvm_eval_mesh.h b/source/blender/blenvm/bvm/bvm_eval_mesh.h
new file mode 100644
index 0000000..5c9e4fb
--- /dev/null
+++ b/source/blender/blenvm/bvm/bvm_eval_mesh.h
@@ -0,0 +1,169 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BVM_EVAL_MESH_H__
+#define __BVM_EVAL_MESH_H__
+
+/** \file bvm_eval_mesh.h
+ *  \ingroup bvm
+ */
+
+extern "C" {
+#include "BLI_math.h"
+}
+
+#include "bvm_eval_common.h"
+
+namespace bvm {
+
+static void eval_op_mesh_load(const EvalData *data, float *stack, StackIndex offset)
+{
+	mesh_ptr p = stack_load_mesh(stack, offset);
+	DerivedMesh *dm = CDDM_from_mesh(data->modifier.base_mesh);
+	p.set(dm);
+	stack_store_mesh(stack, offset, p);
+}
+
+static DerivedMesh *do_array(DerivedMesh *dm, int count, const matrix44 &tfm)
+{
+	const bool use_recalc_normals = (dm->dirty & DM_DIRTY_NORMALS);
+	
+	int chunk_nverts = dm->getNumVerts(dm);
+	int chunk_nedges = dm->getNumEdges(dm);
+	int chunk_nloops = dm->getNumLoops(dm);
+	int chunk_npolys = dm->getNumPolys(dm);
+	
+	/* The number of verts, edges, loops, polys, before eventually merging doubles */
+	int result_nverts = chunk_nverts * count;
+	int result_nedges = chunk_nedges * count;
+	int result_nloops = chunk_nloops * count;
+	int result_npolys = chunk_npolys * count;
+
+	/* Initialize a result dm */
+	DerivedMesh *result = CDDM_from_template(dm, result_nverts, result_nedges, 0, result_nloops, result_npolys);
+	MVert *result_dm_verts = CDDM_get_verts(result);
+
+	/* copy customdata to original geometry */
+	DM_copy_vert_data(dm, result, 0, 0, chunk_nverts);
+	DM_copy_edge_data(dm, result, 0, 0, chunk_nedges);
+	DM_copy_loop_data(dm, result, 0, 0, chunk_nloops);
+	DM_copy_poly_data(dm, result, 0, 0, chunk_npolys);
+
+#if 0 /* XXX is this needed? comment is unintelligible */
+	/* subsurf for eg wont have mesh data in the
+	 * now add mvert/medge/mface layers */
+
+	if (!CustomData_has_layer(&dm->vertData, CD_MVERT)) {
+		dm->copyVertArray(dm, result_dm_verts);
+	}
+	if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE)) {
+		dm->copyEdgeArray(dm, CDDM_get_edges(result));
+	}
+	if (!CustomData_has_layer(&dm->polyData, CD_MPOLY)) {
+		dm->copyLoopArray(dm, CDDM_get_loops(result));
+		dm->copyPolyArray(dm, CDDM_get_polys(result));
+	}
+#endif
+
+	float offset[4][4];
+	transpose_m4_m4(offset, (float (*)[4])tfm.data);
+	float current_offset[4][4];
+	unit_m4(current_offset);
+	
+	for (int c = 1; c < count; c++) {
+		/* copy customdata to new geometry */
+		DM_copy_vert_data(result, result, 0, c * chunk_nverts, chunk_nverts);
+		DM_copy_edge_data(result, result, 0, c * chunk_nedges, chunk_nedges);
+		DM_copy_loop_data(result, result, 0, c * chunk_nloops, chunk_nloops);
+		DM_copy_poly_data(result, result, 0, c * chunk_npolys, chunk_npolys);
+
+		MVert *mv_prev = result_dm_verts;
+		MVert *mv = mv_prev + c * chunk_nverts;
+
+		/* recalculate cumulative offset here */
+		mul_m4_m4m4(current_offset, current_offset, offset);
+
+		/* apply offset to all new verts */
+		for (int i = 0; i < chunk_nverts; i++, mv++, mv_prev++) {
+			mul_m4_v3(current_offset, mv->co);
+
+			/* We have to correct normals too, if we do not tag them as dirty! */
+			if (!use_recalc_normals) {
+				float no[3];
+				normal_short_to_float_v3(no, mv->no);
+				mul_mat3_m4_v3(current_offset, no);
+				normalize_v3(no);
+				normal_float_to_short_v3(mv->no, no);
+			}
+		}
+
+		/* adjust edge vertex indices */
+		MEdge *me = CDDM_get_edges(result) + c * chunk_nedges;
+		for (int i = 0; i < chunk_nedges; i++, me++) {
+			me->v1 += c * chunk_nverts;
+			me->v2 += c * chunk_nverts;
+		}
+
+		MPoly *mp = CDDM_get_polys(result) + c * chunk_npolys;
+		for (int i = 0; i < chunk_npolys; i++, mp++) {
+			mp->loopstart += c * chunk_nloops;
+		}
+
+		/* adjust loop vertex and edge indices */
+		MLoop *ml = CDDM_get_loops(result) + c * chunk_nloops;
+		for (int i = 0; i < chunk_nloops; i++, ml++) {
+			ml->v += c * chunk_nverts;
+			ml->e += c * chunk_nedges;
+		}
+	}
+
+	/* In case org dm has dirty normals, or we made some merging, mark normals as dirty in new dm!
+	 * TODO: we may need to set other dirty flags as well?
+	 */
+	if (use_recalc_normals) {
+		result->dirty = (DMDirtyFlag)(result->dirty | (int)DM_DIRTY_NORMALS);
+	}
+	
+	return result;
+}
+
+static void eval_op_mesh_array(float *stack, StackIndex offset_mesh_in, StackIndex offset_mesh_out,
+                               StackIndex offset_count, Stack

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list