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 5091. Add a Node center of mass for a one or multiple meshes #5092

Conversation

satabol
Copy link
Collaborator

@satabol satabol commented Mar 23, 2024

fix #5091

  • append new node to calculate center of mass for several meshes and total center
  • append docs for this node (without example)

file for tests:

center_of_mass_t1.v003.blend.zip

image

…total center

- append docs for this node (without example)
@@ -0,0 +1,79 @@
Weighted Vector Sum (Alpha)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to name the node "Center of Mass - Mesh" (as opposed to existing Center of Mass node for solids; maybe that node should be renamed to "Center of Mass - Solid", for clarity).

class SvWeightedVectorSumNode(SverchCustomTreeNode, bpy.types.Node, SvRecursiveNode):
"""
Triggers: Bbox 2D or 3D
Tooltip: Get vertices bounding box (vertices, sizes, center)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs update after copy-paste :)

description="Polygons processing mode",
items=ngon_modes,
default="BEAUTY",
update=updateNode) # type: ignore
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to add a checkbox to disable triangulation at all (maybe hide it to the N panel). In case the user knows that the mesh is already tris-only.

Copy link
Collaborator Author

@satabol satabol Mar 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If mode is 'Face' then one can check all faces are tris without any property:
image

but for mode 'Volume' it is not enough: mesh has to be closed and this is a difficult operation. I have suggestion for property 'skip_test_volume_are_closed' and this do real economy for "Volume" mode:

image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this mode do triangulation if some faces are not tris and this back to slowdown performance but user get good result.

area_I = areases_I.sum()
tris_centers_I = tris_I.sum(axis=1) / 3.0
center_mass_mesh_I = (tris_centers_I * areases_I[np.newaxis].T).sum(axis=0) / area_I
mass_I = area_I * density_I[0]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say core algorithms should be moved to sverchok.utils.geom, and just be called from the node.

volume_I = signed_volumes_I.sum()
tetra_centers_I = tris_I.sum(axis=1) / 4.0
center_mass_mesh_I = (tetra_centers_I * signed_volumes_I[np.newaxis].T).sum(axis=0) / volume_I
mass_I = volume_I * density_I[0]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same, to geom.py.

self.outputs['output_edges'] .label = 'Edges'
self.outputs['output_polygons'] .label = 'Polygons'
self.outputs['output_centers_of_mass'].label = 'Centers mass of objects'
self.outputs['output_total_center'].label = 'Total center'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Common center"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So many centers. I mean “Center of all objects”. May be last is good?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

Copy link
Collaborator Author

@satabol satabol Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it good?
image
To see changes you need recreate node.

self.outputs['output_vertices'] .label = 'Vertices'
self.outputs['output_edges'] .label = 'Edges'
self.outputs['output_polygons'] .label = 'Polygons'
self.outputs['output_centers_of_mass'].label = 'Centers mass of objects'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Centers of mass of objects"

# test if all edges are contiguous (https://docs.blender.org/api/current/bmesh.types.html#bmesh.types.BMEdge.is_contiguous)
# then volume is closed:
for edge in bm_I.edges:
if edge.is_contiguous==False:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also probably needs a flag to disable this check. If the user already knows the volume is closed, this is just a waste of time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

satabol added 3 commits March 24, 2024 19:18
  - rename node name in menu
  - append a param skip_test_volume_are_closed (only for volume mode)
  - append test triangulation before call bmesh utils for Face and Volume modes
@satabol
Copy link
Collaborator Author

satabol commented Mar 24, 2024

@portnov

for tests:
center_of_mass_t1.v004.blend.zip

@@ -912,3 +913,186 @@ def recalc_normals(verts, edges, faces, loop=False):
verts, edges, faces = pydata_from_bmesh(bm)
bm.free()
return verts, edges, faces

def calc_center_mass_bmesh(center_mode, vertices_I, edges_I, faces_I, mass_of_vertices_I=[1], density_I=[1], skip_test_volume_are_closed=False, quad_mode="BEAUTY", ngon_mode="BEAUTY"):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In python, it's bad idea to use potentially mutable values as default values for arguments. Basically you have to do def calc_center_mass_bmesh(mass_of_vertices_I = None), and then if mass_of_vertices_I is None: mass_of_vertices = [1].

Also, why _I ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix [1] to None.
_I - I use it in “for” before. It show all data connect to one object (I-th object).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you read this method, you shouldn't have to remember that it is called in a loop :) In another place it can be called without a loop. So, while _I names are okay in context of loop, as names of method parameter this does not make sense, imho.

Copy link
Collaborator Author

@satabol satabol Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Fixed. )

@satabol satabol merged commit 86fb2ee into master Apr 5, 2024
1 of 2 checks passed
@satabol satabol deleted the fix_5091_Add_a_Node_center_of_mass_for_a_one_or_multiple_meshes branch April 5, 2024 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a Node center of mass for a one or multiple meshes
2 participants