Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #5019 extend node "get object data" with options "apply matrix" and "join mesh" (merge) #5022

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/nodes/scene/get_objects_data.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Get Objects Data
================

.. image:: https://github.com/nortikin/sverchok/assets/14288520/866c67a1-c6ea-4db5-be8e-e5981c7c5aad
:target: https://github.com/nortikin/sverchok/assets/14288520/866c67a1-c6ea-4db5-be8e-e5981c7c5aad
.. image:: https://github.com/nortikin/sverchok/assets/14288520/b24e7fbc-3383-49ca-bc96-ae5ff823fee3
:target: https://github.com/nortikin/sverchok/assets/14288520/b24e7fbc-3383-49ca-bc96-ae5ff823fee3

Functionality
-------------
Expand Down
90 changes: 90 additions & 0 deletions docs/old/nodes/get_objects_data.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
:orphan:

Get Objects Data
================

.. image:: https://github.com/nortikin/sverchok/assets/14288520/b24e7fbc-3383-49ca-bc96-ae5ff823fee3
:target: https://github.com/nortikin/sverchok/assets/14288520/b24e7fbc-3383-49ca-bc96-ae5ff823fee3

Functionality
-------------
Get objects from the Blender ``Scene`` and output them into Sverchok's node tree. This node supports most object types. All are converted to a Sverchok representation of ``Mesh`` where possible.

A few points worth stating explicitly.

- Empties, Cameras, and Lamps produce only matrix data.
- The order of the selected Objects can be sorted by name.
- It supports Object collections.
- It understands also ``vertex groups``, when activated, showing additional socket representing indices, that you can use for further processing. All groups are cached in one list _without_weights_.
- When you ``Get`` objects from the Scene that have modifiers on them, you can import the final mesh by enabling the ``Post`` button.
- Importing Objects with a lot of geometry will decrease Sverchok tree update speed, be careful with any modifiers that produce a lot of extra geometry (like subdivision modifier)
- The Matrix socket lets you ignore or acquire the Object's ``World Matrix``, by default the Object data is untransformed. Use a matrix-apply node if you want to explicitly transform the vertex data.

limitations:

- When you use the ``Post`` mode Sverchok/Blender expect Objects to be visible. If you want to "hide" the original Objects in the scene to avoid visual clutter, you can place them into a Collection and hide the collection. This is a current Blender API limitation.
- We have Bezier-in and NURBS-in nodes if you want to get Curve data from Scene objects, instead of Mesh.

Inputs
------

Objects Socket


Parameters
----------

+-----------------+---------------+--------------------------------------------------------------------------+
| Param | Type | Description |
+=================+===============+==========================================================================+
| **G E T** | Button | Button to get selected objects from scene. |
+-----------------+---------------+--------------------------------------------------------------------------+
| **sorting** | Bool, toggle | Sorting inserted objects by name |
+-----------------+---------------+--------------------------------------------------------------------------+
| **post** | Bool, toggle | Postprocessing, if activated, modifiers applied to mesh before importing |
+-----------------+---------------+--------------------------------------------------------------------------+
| **vert groups** | Bool, toggle | Import all vertex groups that in object's data. just import indexes |
+-----------------+---------------+--------------------------------------------------------------------------+

3D panel
--------

The node can show its properties on 3D panel.
For this parameter `to 3d` should be enabled, output should be linked.
After that you can press `scan for props` button on 3D panel for showing the node properties on 3D panel.

Outputs
-------

+------------------+--------------------------------------------------------------------------+
| Output | Description |
+==================+==========================================================================+
| Vertices | Vertices of objects |
+------------------+--------------------------------------------------------------------------+
| Edges | Edges of objects |
+------------------+--------------------------------------------------------------------------+
| Polygons | Polygons of objects |
+------------------+--------------------------------------------------------------------------+
| Vertex Normals | Vertex Normals |
+------------------+--------------------------------------------------------------------------+
| Material Idx | Material indexes per object face. |
+------------------+--------------------------------------------------------------------------+
| Polygons Areas | Polygons of objects. |
+------------------+--------------------------------------------------------------------------+
| Polygons Centers | Polygons Center of objects. |
+------------------+--------------------------------------------------------------------------+
| Polygons Normal | Polygons Normal of objects. |
+------------------+--------------------------------------------------------------------------+
| Matrix | Matrices of objects |
+------------------+--------------------------------------------------------------------------+
| Vers grouped | Vertex groups' indices from all vertex groups |
+------------------+--------------------------------------------------------------------------+

It can output Numpy arrays of vertices and edges if enabled on N-panel properties (makes node faster)

Examples
--------

.. image:: https://user-images.githubusercontent.com/619340/126961901-4c300e39-6cbe-456f-a132-104f7b3827ca.png

Importing an object with two array modifiers applied and showing indices.
2 changes: 1 addition & 1 deletion index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@
- Scene:
- icon_name: SCENE_DATA
- extra_menu: ConnectionPartialMenu
- SvGetObjectsData
- SvGetObjectsDataMK2
- SvObjInLite
- SvCurveInputNode
- SvFCurveInNodeMK1
Expand Down
Binary file modified json_examples/Advanced/Pineapple.zip.zip
Binary file not shown.
4 changes: 2 additions & 2 deletions json_examples/Introduction/Adaptive_Spread.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"width": 200.0
},
"Get Objects Data": {
"bl_idname": "SvGetObjectsData",
"bl_idname": "SvGetObjectsDataMK2",
"color": [
0.0,
0.5,
Expand All @@ -76,7 +76,7 @@
"width": 140.0
},
"Get Objects Data.001": {
"bl_idname": "SvGetObjectsData",
"bl_idname": "SvGetObjectsDataMK2",
"color": [
0.0,
0.5,
Expand Down
2 changes: 1 addition & 1 deletion menus/full_by_data_type.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@
- Scene:
- icon_name: SCENE_DATA
- extra_menu: ConnectionPartialMenu
- SvGetObjectsData
- SvGetObjectsDataMK2
- SvObjInLite
- SvCurveInputNode
- SvFCurveInNodeMK1
Expand Down
2 changes: 1 addition & 1 deletion menus/full_nortikin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@
- Scene:
- icon_name: SCENE_DATA
- extra_menu: ConnectionPartialMenu
- SvGetObjectsData
- SvGetObjectsDataMK2
- SvObjInLite
- SvCurveInputNode
- SvFCurveInNodeMK1
Expand Down
146 changes: 116 additions & 30 deletions nodes/scene/get_objects_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
import bpy
from bpy.props import BoolProperty, StringProperty, IntProperty
import bmesh
from mathutils import Vector, Matrix

from sverchok.node_tree import SverchCustomTreeNode
from sverchok.utils.sv_operator_mixins import SvGenericNodeLocator
from sverchok.data_structure import updateNode
from sverchok.utils.sv_bmesh_utils import pydata_from_bmesh
from sverchok.utils.sv_mesh_utils import mesh_join
from sverchok.utils.nodes_mixins.show_3d_properties import Show3DProperties
from sverchok.utils.blender_mesh import (
read_verts, read_edges, read_verts_normal,
read_face_normal, read_face_center, read_face_area, read_materials_idx)
import numpy as np


class SvOB3BDataCollectionMK2(bpy.types.PropertyGroup):
Expand Down Expand Up @@ -81,13 +84,13 @@ def get_vertgroups(mesh):
numpy_socket_names = ['Vertices', 'Edges', 'Vertex Normals', 'Material Idx', 'Polygon Areas', 'Polygon Centers', 'Polygon Normals']


class SvGetObjectsData(Show3DProperties, SverchCustomTreeNode, bpy.types.Node):
class SvGetObjectsDataMK2(Show3DProperties, SverchCustomTreeNode, bpy.types.Node):
"""
Triggers: Object Info
Tooltip: Get Scene Objects into Sverchok Tree
"""

bl_idname = 'SvGetObjectsData'
bl_idname = 'SvGetObjectsDataMK2'
bl_label = 'Get Objects Data'
bl_icon = 'OUTLINER_OB_EMPTY'
sv_icon = 'SV_OBJECTS_IN'
Expand Down Expand Up @@ -138,10 +141,23 @@ def hide_show_versgroups(self, context):
name='Output all numpy',
description='Output numpy arrays if possible',
default=False, update=updateNode)


apply_matrix: BoolProperty(
name = "Apply matrices",
description = "Apply objects matrices",
default = True,
update = updateNode)

mesh_join : BoolProperty(
name = "merge",
description = "If checked, join mesh elements into one object",
default = False,
update = updateNode)

def sv_init(self, context):
new = self.outputs.new
self.width = 150
self.width = 170
self.inputs.new('SvObjectSocket', "Objects")
new('SvVerticesSocket', "Vertices")
new('SvStringsSocket', "Edges")
Expand Down Expand Up @@ -212,6 +228,11 @@ def sv_draw_buttons(self, context, layout):

self.wrapper_tracked_ui_draw_op(row, callback, text=op_text).fn_name = 'get_objects_from_scene'

col = layout.column(align=True)
row = col.row(align=True)
row.prop(self, "apply_matrix", text="Apply matrix", toggle=True)
row.prop(self, "mesh_join", text="merge", toggle=True)

col = layout.column(align=True)
row = col.row(align=True)
if not by_input:
Expand Down Expand Up @@ -296,24 +317,24 @@ def process(self):
# from 3dview while in edit mode when using obj.to_mesh.
me = obj.data
bm = bmesh.from_edit_mesh(me)
vers, edgs, pols = pydata_from_bmesh(bm)
# verts, edgs, pols = pydata_from_bmesh(bm)

if o_vs:
vs.append(vers)
verts = [ Vector(v.co) for v in bm.verts] # v.co is a Vector()
zeffii marked this conversation as resolved.
Show resolved Hide resolved
if o_es:
es.append(edgs)
edgs = [[e.verts[0].index, e.verts[1].index] for e in bm.edges]
if o_ps:
ps.append(pols)
pols = [[i.index for i in p.verts] for p in bm.faces]
if o_vn:
vn.append([v.normal[:] for v in bm.verts])
vertex_normals = [ Vector(v.normal) for v in bm.verts] # v.normal is a Vector()
if o_mi:
mi.append(self.get_materials_from_bmesh(bm))
material_indexes = self.get_materials_from_bmesh(bm)
if o_pa:
pa.append([p.calc_area() for p in bm.faces])
polygons_areas = [ p.calc_area() for p in bm.faces ]
if o_pc:
pc.append([p.calc_center_median()[:] for p in bm.faces])
polygon_centers = [ Vector(p.calc_center_median()) for p in bm.faces ]
if o_pn:
pn.append([p.normal[:] for p in bm.faces])
polygon_normals = [ Vector(p.normal) for p in bm.faces ]

del bm
else:
Expand All @@ -326,33 +347,48 @@ def process(self):
obj_data = obj.to_mesh(preserve_all_data_layers=True, depsgraph=sv_depsgraph)
else:
obj_data = obj.to_mesh()

T, R, S = mtrx.decompose()

if o_vs:
vs.append(read_verts(obj_data, out_np[0]))
verts = [ ((mtrx @ v.co) if self.apply_matrix else v.co)[:] for v in obj_data.vertices] # v.co is a Vector()
if o_es:
es.append(read_edges(obj_data, out_np[1]))
edgs = [[ e.vertices[0], e.vertices[1] ] for e in obj_data.edges]
if o_ps:
ps.append([list(p.vertices) for p in obj_data.polygons])
pols = [list(p.vertices) for p in obj_data.polygons]
if self.vergroups:
vers_out_grouped.append(get_vertgroups(obj_data))
vert_groups = get_vertgroups(obj_data)
if o_vn:
vn.append(read_verts_normal(obj_data, out_np[2]))
vertex_normals = [ (( R @ v.co) if self.apply_matrix else v.normal)[:] for v in obj_data.vertices ] # v.normal is a Vector(). Update. Blender 3.6.3 crash in no wrap Vector(v.normal). I think this is after line "obj.to_mesh_clear()"
if o_mi:
mi.append(read_materials_idx(obj_data, out_np[3]))
material_indexes = read_materials_idx(obj_data, out_np[3])
if o_pa:
pa.append(read_face_area(obj_data, out_np[4]))
polygons_areas = [ polygon.area for polygon in obj_data.polygons]
if o_pc:
if out_np[5]:
pc.append(read_face_center(obj_data, output_numpy=True))
else:
pc.append([p.center[:] for p in obj_data.polygons])
polygon_centers = [ ((mtrx @ polygon.center) if self.apply_matrix else polygon.center)[:] for polygon in obj_data.polygons]
if o_pn:
if out_np[6]:
pn.append(read_face_normal(obj_data, True))
else:
pn.append([p.normal[:] for p in obj_data.polygons])

obj.to_mesh_clear()
polygon_normals = [ (( R @ polygon.normal) if self.apply_matrix else polygon.normal)[:] for polygon in obj_data.polygons]

obj.to_mesh_clear()

if o_vs:
vs.append( verts )
if o_es:
es.append( edgs )
if o_ps:
ps.append( pols )
if self.vergroups:
vers_out_grouped.append( vert_groups )
if o_vn:
vn.append( vertex_normals )
if o_mi:
mi.append( material_indexes )
if o_pa:
pa.append( polygons_areas )
if o_pc:
pc.append( polygon_centers )
if o_pn:
pn.append( polygon_normals )

except ReadingObjectDataError:
raise
Expand All @@ -364,6 +400,56 @@ def process(self):
if o_ms:
ms.append(mtrx)

if self.mesh_join:
# vs, es, ps, vn, mi, pa, pc, pn, ms
offset = 0
_vs = []
_es, _ps, _vn, _pa, _pc, _pn, _vg = [], [], [], [], [], [], []
for idx, vertices in enumerate(vs):
_vs.extend(vertices)
if es:
_es.extend( [[i + offset for i in o] for o in es[idx] ] ) # edges
if ps:
_ps.extend( [[i + offset for i in o] for o in ps[idx] ] ) # polygons
#_vn.extend( [tuple(i + offset for i in o) for o in ps[idx] ] ) # vers_out_grouped. Skip in mesh_join
if vn:
_vn.extend( vn[idx] ) # vertex normals
# _mi - materia index. Do not change
# if mi and len(mi)>idx:
# _mi.extend( mi[idx] ) # Skip in mesh_join
if pa:
_pa.extend( pa[idx] ) # polygon area
if pc:
_pc.extend( pc[idx] ) # polygon center
if pn:
_pn.extend( pn[idx] ) # polygon normal
# if ms: Do not change
# _ms.append( ms[idx] ) # matrices. Skip in mesh_join
if vers_out_grouped:
_vg.extend( [ i + offset for i in vers_out_grouped[idx] ] ) # vertex groups

offset += len(vertices)

vs, es, ps, vn, pa, pc, pn, vers_out_grouped = [_vs], [_es], [_ps], [_vn], [_pa], [_pc], [_pn], [_vg]

if o_vs and (out_np[0]):
vs = [np.array(vert) for vert in vs]
if o_es and (out_np[1]):
es = [np.array(edge) for edge in es]
# if o_ps and (out_np[2]):
# ps = [np.array(pol) for pol in ps]
# if self.vergroups:
# vers_out_grouped = [np.array(group) for group in vers_out_grouped]
if o_vn and (out_np[2]):
vn = [np.array(vert_normal) for vert_normal in vn]
if o_mi and (out_np[3]):
mi = [np.array(material_index) for material_index in mi]
if o_pa and (out_np[4]):
pa = [np.array(polygon_areas) for polygon_areas in pa]
if o_pc and (out_np[5]):
pc = [np.array(polygon_centers) for polygon_centers in pc]
if o_pn and (out_np[6]):
pn = [np.array(polygon_normals) for polygon_normals in pn]

for i, i2 in zip(self.outputs, [vs, es, ps, vn, mi, pa, pc, pn, ms]):
if i.is_linked:
Expand All @@ -379,5 +465,5 @@ def process(self):
outputs['Object'].sv_set([data_objects.get(o.name) for o in self.object_names])


classes = [SvOB3BItemOperatorMK2, SvOB3BDataCollectionMK2, SVOB3B_UL_NamesListMK2, SvOB3CallbackMK2, SvGetObjectsData]
classes = [SvOB3BItemOperatorMK2, SvOB3BDataCollectionMK2, SVOB3B_UL_NamesListMK2, SvOB3CallbackMK2, SvGetObjectsDataMK2]
register, unregister = bpy.utils.register_classes_factory(classes)
Loading
Loading