From 0ceef6c396c7bdbbc9b8c02ba580dbec5a3db6d6 Mon Sep 17 00:00:00 2001 From: zeffii Date: Sun, 4 Jun 2017 17:06:21 +0200 Subject: [PATCH 1/9] pcloud initial, unvectorized version --- index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/index.md b/index.md index de7dde7d1..31a635e74 100644 --- a/index.md +++ b/index.md @@ -186,6 +186,7 @@ SvInterpolationNodeMK2 SvInterpolationNodeMK3 --- + SvHomogenousVectorField SvNoiseNodeMK2 SvVectorFractal SvLacunarityNode -- GitLab From 47f96fd6bcd962e59bcb792eaa9bb014741b3a0b Mon Sep 17 00:00:00 2001 From: zeffii Date: Sun, 4 Jun 2017 18:45:56 +0200 Subject: [PATCH 2/9] add file to git --- nodes/vector/homogenous_vector_field.py | 100 ++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 nodes/vector/homogenous_vector_field.py diff --git a/nodes/vector/homogenous_vector_field.py b/nodes/vector/homogenous_vector_field.py new file mode 100644 index 000000000..ea9c00e75 --- /dev/null +++ b/nodes/vector/homogenous_vector_field.py @@ -0,0 +1,100 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +import numpy as np + +import bpy +import bmesh +# import mathutils +# from mathutils import Vector +from bpy.props import FloatProperty, IntProperty +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode +from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata, pydata_from_bmesh + +class SvHomogenousVectorField(bpy.types.Node, SverchCustomTreeNode): + ''' hv evenly spaced vfield ''' + bl_idname = 'SvHomogenousVectorField' + bl_label = 'pcloud' + + xdim__ = IntProperty(default=2, min=1, update=updateNode) + ydim__ = IntProperty(default=3, min=1, update=updateNode) + zdim__ = IntProperty(default=4, min=1, update=updateNode) + sizex__ = FloatProperty(default=1.0, min=1.0, update=updateNode) + sizey__ = FloatProperty(default=1.0, min=1.0, update=updateNode) + sizez__ = FloatProperty(default=1.0, min=1.0, update=updateNode) + seed = IntProperty(default=0, min=0, update=updateNode) + + randomize_factor = FloatProperty(name='randomize', default=0.0, min=0.0, update=updateNode) + rm_doubles_distance = FloatProperty(name='rm distance', default=0.0, update=updateNode) + + def sv_init(self, context): + self.inputs.new("StringsSocket", "xdim").prop_name='xdim__' + self.inputs.new("StringsSocket", "ydim").prop_name='ydim__' + self.inputs.new("StringsSocket", "zdim").prop_name='zdim__' + self.inputs.new("StringsSocket", "size x").prop_name='sizex__' + self.inputs.new("StringsSocket", "size y").prop_name='sizey__' + self.inputs.new("StringsSocket", "size z").prop_name='sizez__' + self.outputs.new("VerticesSocket", "verts") + + def draw_buttons(self, context, layout): + col = layout.column(align=True) + col.prop(self, 'randomize_factor') + col.prop(self, 'rm_doubles_distance') + col.prop(self, 'seed') + + def process(self): + + xdims, ydims, zdims, sizesx, sizesy, sizesz = [s.sv_get()[0] for s in self.inputs] + + verts = [] + for xdim, ydim, zdim, *size in zip(xdims, ydims, zdims, sizesx, sizesy, sizesz): + hs0 = size[0] / 2 + hs1 = size[1] / 2 + hs2 = size[2] / 2 + + + x_ = np.linspace(-hs0, hs0, xdim) + y_ = np.linspace(-hs1, hs1, ydim) + z_ = np.linspace(-hs2, hs2, zdim) + + f = np.vstack(np.meshgrid(x_,y_,z_)).reshape(3,-1).T + num_items = f.shape[0]* f.shape[1] + + if self.randomize_factor > 0.0: + np.random.seed(self.seed) + noise = (np.random.normal(0, 0.5, num_items) * self.randomize_factor).reshape(3,-1).T + f += noise + + f = f.tolist() + if self.rm_doubles_distance > 0.0: + bm = bmesh_from_pydata(f, [], []) + bmesh.ops.remove_doubles(bm, verts=bm.verts[:], dist=self.rm_doubles_distance) + f, _, _ = pydata_from_bmesh(bm) + + verts.append(f) + + if verts: + self.outputs['verts'].sv_set(verts) + +def register(): + bpy.utils.register_class(SvHomogenousVectorField) + + +def unregister(): + bpy.utils.unregister_class(SvHomogenousVectorField) \ No newline at end of file -- GitLab From 13d5055d54b4e968929f3c751e464a197fed524a Mon Sep 17 00:00:00 2001 From: zeffii Date: Mon, 5 Jun 2017 10:29:04 +0200 Subject: [PATCH 3/9] add points_inside_mesh node --- index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/index.md b/index.md index 31a635e74..4c06d3056 100644 --- a/index.md +++ b/index.md @@ -56,6 +56,7 @@ SvEdgeAnglesNode SvMeshSelectNode SvSelectSimilarNode + SvPointInside SvProportionalEditNode ## Transforms -- GitLab From 593297846a6a9d1389409d1758d53a544e00b22a Mon Sep 17 00:00:00 2001 From: zeffii Date: Mon, 5 Jun 2017 10:30:01 +0200 Subject: [PATCH 4/9] add points_inside_mesh node --- nodes/analyzer/points_inside_mesh.py | 91 ++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 nodes/analyzer/points_inside_mesh.py diff --git a/nodes/analyzer/points_inside_mesh.py b/nodes/analyzer/points_inside_mesh.py new file mode 100644 index 000000000..d43d40824 --- /dev/null +++ b/nodes/analyzer/points_inside_mesh.py @@ -0,0 +1,91 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +import bpy +import bmesh +from mathutils.kdtree import KDTree +from mathutils import Vector + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode +from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata + + +def are_inside(points, bm): + rpoints = [] + addp = rpoints.append + + if len(bm.verts) <= 8: + bmesh.ops.subdivide_edges(bm, edges=bm.edges[:], smooth=False) + + size = len(bm.verts) + kd = KDTree(size) + for i, xyz in enumerate(bm.verts): + kd.insert(xyz.co[:], i) + kd.balance() + + # bm.verts.ensure_lookup_table() + + verts = bm.verts + for p in points: + co, index, _ = kd.find(p) + normal = verts[index].normal + p2 = co - Vector(p) + v = p2.dot(normal) + addp(not v < 0.0) # addp(v >= 0.0) ? + + return rpoints + + + +class SvPointInside(bpy.types.Node, SverchCustomTreeNode): + ''' pin get points inside mesh ''' + bl_idname = 'SvPointInside' + bl_label = 'Points Inside Mesh' + + def sv_init(self, context): + self.inputs.new('VerticesSocket', 'verts') + self.inputs.new('VerticesSocket', 'faces') + self.inputs.new('VerticesSocket', 'verts') + self.outputs.new('StringsSocket', 'mask') + self.outputs.new('VerticesSocket', 'verts') + + def process(self): + + # no vectorization yet + + verts_in, faces_in, points = [s.sv_get() for s in self.inputs] + + mask = [] + for idx, (verts, faces, pts_in) in enumerate(zip(verts_in, faces_in, points)): + bm = bmesh_from_pydata(verts, [], faces, normal_update=True) + mask.append(are_inside(pts_in, bm)) + + self.outputs['mask'].sv_set(mask) + if self.outputs['verts'].is_linked: + out_verts = [] + for masked, pts_in in zip(mask, points): + out_verts.append([p for m, p in zip(masked, pts_in) if m]) + + +def register(): + bpy.utils.register_class(SvPointInside) + + +def unregister(): + bpy.utils.unregister_class(SvPointInside) -- GitLab From 6860f5c765c4f39c19ad1d49097ee0c245cd2783 Mon Sep 17 00:00:00 2001 From: zeffii Date: Mon, 5 Jun 2017 19:49:33 +0200 Subject: [PATCH 5/9] add division feature for minimally divided meshes --- nodes/analyzer/points_inside_mesh.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/nodes/analyzer/points_inside_mesh.py b/nodes/analyzer/points_inside_mesh.py index d43d40824..d304578da 100644 --- a/nodes/analyzer/points_inside_mesh.py +++ b/nodes/analyzer/points_inside_mesh.py @@ -31,7 +31,8 @@ def are_inside(points, bm): addp = rpoints.append if len(bm.verts) <= 8: - bmesh.ops.subdivide_edges(bm, edges=bm.edges[:], smooth=False) + bmesh.ops.subdivide_edges(bm, edges=bm.edges[:], cuts=6, use_grid_fill=True) + bm.verts.ensure_lookup_table() size = len(bm.verts) kd = KDTree(size) @@ -40,7 +41,6 @@ def are_inside(points, bm): kd.balance() # bm.verts.ensure_lookup_table() - verts = bm.verts for p in points: co, index, _ = kd.find(p) @@ -52,7 +52,6 @@ def are_inside(points, bm): return rpoints - class SvPointInside(bpy.types.Node, SverchCustomTreeNode): ''' pin get points inside mesh ''' bl_idname = 'SvPointInside' @@ -60,15 +59,14 @@ class SvPointInside(bpy.types.Node, SverchCustomTreeNode): def sv_init(self, context): self.inputs.new('VerticesSocket', 'verts') - self.inputs.new('VerticesSocket', 'faces') - self.inputs.new('VerticesSocket', 'verts') + self.inputs.new('StringsSocket', 'faces') + self.inputs.new('VerticesSocket', 'points') self.outputs.new('StringsSocket', 'mask') self.outputs.new('VerticesSocket', 'verts') def process(self): # no vectorization yet - verts_in, faces_in, points = [s.sv_get() for s in self.inputs] mask = [] @@ -81,6 +79,7 @@ class SvPointInside(bpy.types.Node, SverchCustomTreeNode): out_verts = [] for masked, pts_in in zip(mask, points): out_verts.append([p for m, p in zip(masked, pts_in) if m]) + self.outputs['verts'].sv_set(out_verts) def register(): -- GitLab From b53d7511f601d18ed8135cfabe6692a3da7a90ed Mon Sep 17 00:00:00 2001 From: zeffii Date: Tue, 6 Jun 2017 18:37:59 +0200 Subject: [PATCH 6/9] add rst --- docs/nodes/vector/homogenous_vector_field.rst | 9 ++++++ docs/nodes/vector/vector_index.rst | 1 + nodes/analyzer/points_inside_mesh.py | 28 ++++++------------- nodes/vector/homogenous_vector_field.py | 8 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) create mode 100644 docs/nodes/vector/homogenous_vector_field.rst diff --git a/docs/nodes/vector/homogenous_vector_field.rst b/docs/nodes/vector/homogenous_vector_field.rst new file mode 100644 index 000000000..127757ee4 --- /dev/null +++ b/docs/nodes/vector/homogenous_vector_field.rst @@ -0,0 +1,9 @@ +Vector P Field +============== + +Functionality +------------- + + +makes a 3d vector grid, with option to slightly randomize (with seed) each vertex, and apply a 'remove doubles' distance to the product. + diff --git a/docs/nodes/vector/vector_index.rst b/docs/nodes/vector/vector_index.rst index 682447b1e..ada5b30ee 100644 --- a/docs/nodes/vector/vector_index.rst +++ b/docs/nodes/vector/vector_index.rst @@ -15,6 +15,7 @@ Vector noise_mk2 fractal lerp + homogenous_vector_field vector_rewire vector_in vector_out diff --git a/nodes/analyzer/points_inside_mesh.py b/nodes/analyzer/points_inside_mesh.py index d304578da..89fcd57d9 100644 --- a/nodes/analyzer/points_inside_mesh.py +++ b/nodes/analyzer/points_inside_mesh.py @@ -18,8 +18,9 @@ import bpy import bmesh -from mathutils.kdtree import KDTree from mathutils import Vector +from mathutils.kdtree import KDTree +from mathutils.bvhtree import BVHTree from sverchok.node_tree import SverchCustomTreeNode from sverchok.data_structure import updateNode @@ -29,26 +30,15 @@ from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata def are_inside(points, bm): rpoints = [] addp = rpoints.append - - if len(bm.verts) <= 8: - bmesh.ops.subdivide_edges(bm, edges=bm.edges[:], cuts=6, use_grid_fill=True) - bm.verts.ensure_lookup_table() - - size = len(bm.verts) - kd = KDTree(size) - for i, xyz in enumerate(bm.verts): - kd.insert(xyz.co[:], i) - kd.balance() - - # bm.verts.ensure_lookup_table() - verts = bm.verts - for p in points: - co, index, _ = kd.find(p) - normal = verts[index].normal - p2 = co - Vector(p) + bvh = BVHTree.FromBMesh(bm, epsilon=0.0001) + + # return points on polygons + for point in points: + fco, normal, _, _ = bvh.find_nearest(point) + p2 = fco - Vector(point) v = p2.dot(normal) addp(not v < 0.0) # addp(v >= 0.0) ? - + return rpoints diff --git a/nodes/vector/homogenous_vector_field.py b/nodes/vector/homogenous_vector_field.py index ea9c00e75..be676f24f 100644 --- a/nodes/vector/homogenous_vector_field.py +++ b/nodes/vector/homogenous_vector_field.py @@ -30,14 +30,14 @@ from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata, pydata_from_bmesh class SvHomogenousVectorField(bpy.types.Node, SverchCustomTreeNode): ''' hv evenly spaced vfield ''' bl_idname = 'SvHomogenousVectorField' - bl_label = 'pcloud' + bl_label = 'Vector P Field' xdim__ = IntProperty(default=2, min=1, update=updateNode) ydim__ = IntProperty(default=3, min=1, update=updateNode) zdim__ = IntProperty(default=4, min=1, update=updateNode) - sizex__ = FloatProperty(default=1.0, min=1.0, update=updateNode) - sizey__ = FloatProperty(default=1.0, min=1.0, update=updateNode) - sizez__ = FloatProperty(default=1.0, min=1.0, update=updateNode) + sizex__ = FloatProperty(default=1.0, min=.01, update=updateNode) + sizey__ = FloatProperty(default=1.0, min=.01, update=updateNode) + sizez__ = FloatProperty(default=1.0, min=.01, update=updateNode) seed = IntProperty(default=0, min=0, update=updateNode) randomize_factor = FloatProperty(name='randomize', default=0.0, min=0.0, update=updateNode) -- GitLab From e484096899bb9e03b0b1f50ba191cff5303e42d6 Mon Sep 17 00:00:00 2001 From: zeffii Date: Tue, 6 Jun 2017 18:42:54 +0200 Subject: [PATCH 7/9] adds the prelim doc for points inside --- docs/nodes/analyzers/analyzers_index.rst | 1 + docs/nodes/analyzers/points_inside_mesh.rst | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 docs/nodes/analyzers/points_inside_mesh.rst diff --git a/docs/nodes/analyzers/analyzers_index.rst b/docs/nodes/analyzers/analyzers_index.rst index 984bf500e..8a62a1170 100644 --- a/docs/nodes/analyzers/analyzers_index.rst +++ b/docs/nodes/analyzers/analyzers_index.rst @@ -17,6 +17,7 @@ Analyzers proportional normal normals + points_inside_mesh polygons_centers polygons_centers_mk3 raycast diff --git a/docs/nodes/analyzers/points_inside_mesh.rst b/docs/nodes/analyzers/points_inside_mesh.rst new file mode 100644 index 000000000..976382abf --- /dev/null +++ b/docs/nodes/analyzers/points_inside_mesh.rst @@ -0,0 +1,9 @@ +Points Inside Mesh +================== + +Functionality +------------- + +This node takes a list of probe points, and an associated manifold boundary mesh (verts, faces). It analyses for each of the probe points whether it is located inside or outside of the boundary mesh. + +A small implementation issue is the imprecise categorization when the associated boundary mesh is low poly. \ No newline at end of file -- GitLab From 323c415465fc0205559ed1cb8a20b5c2ff9b841f Mon Sep 17 00:00:00 2001 From: zeffii Date: Tue, 6 Jun 2017 18:43:44 +0200 Subject: [PATCH 8/9] add more to rst --- docs/nodes/analyzers/points_inside_mesh.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/nodes/analyzers/points_inside_mesh.rst b/docs/nodes/analyzers/points_inside_mesh.rst index 976382abf..608aec006 100644 --- a/docs/nodes/analyzers/points_inside_mesh.rst +++ b/docs/nodes/analyzers/points_inside_mesh.rst @@ -6,4 +6,6 @@ Functionality This node takes a list of probe points, and an associated manifold boundary mesh (verts, faces). It analyses for each of the probe points whether it is located inside or outside of the boundary mesh. -A small implementation issue is the imprecise categorization when the associated boundary mesh is low poly. \ No newline at end of file +A small implementation issue is the imprecise categorization when the associated boundary mesh is low poly. + +Warning. This is only a first implementation, likely it will be more correct after a few iterations. \ No newline at end of file -- GitLab From a90ec0e9f2095eb664cf11fe6deec5c1574168e7 Mon Sep 17 00:00:00 2001 From: zeffii Date: Tue, 6 Jun 2017 18:45:38 +0200 Subject: [PATCH 9/9] add more to rst link --- docs/nodes/analyzers/points_inside_mesh.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/nodes/analyzers/points_inside_mesh.rst b/docs/nodes/analyzers/points_inside_mesh.rst index 608aec006..0a70babb5 100644 --- a/docs/nodes/analyzers/points_inside_mesh.rst +++ b/docs/nodes/analyzers/points_inside_mesh.rst @@ -8,4 +8,6 @@ This node takes a list of probe points, and an associated manifold boundary mesh A small implementation issue is the imprecise categorization when the associated boundary mesh is low poly. -Warning. This is only a first implementation, likely it will be more correct after a few iterations. \ No newline at end of file +Warning. This is only a first implementation, likely it will be more correct after a few iterations. + +see https://github.com/nortikin/sverchok/pull/1703 \ No newline at end of file -- GitLab