Closed Nicolaus93 closed 2 weeks ago
Hello @Nicolaus93 !
It is because union
is a volumetric operation: it only works when both operands are closed meshes, that define an interior and an exterior. What you want to do is to merge meshes.
To (blindly) merge the content of two meshes, you can use:
S = ... # some mesh
T = .. # another mesh
S.I.Mesh.merge(T)
After that, you may want to merge duplicated vertices:
S.I.Surface.merge_vertices()
Or maybe you want to compute intersections:
S.I.Surface.intersect(remove_internal_shells=False)
Note: if you want to have more information about a function (and if you updated geogram and Graphite this morning), you can use, for instance:
S.I.Surface.help()
and it will say:
============
OGF::MeshGrobSurfaceCommands::intersect(remove_internal_shells,simplify_coplanar_facets,coplanar_angle_tolerance,interpolate_attributes)
Computes intersections in a surface mesh
Parameters
==========
remove_internal_shells : bool = true
keep only facets on external hull
simplify_coplanar_facets : bool = true
retriangulates planar zones
coplanar_angle_tolerance : double = 0.001
in degrees
interpolate_attributes : bool = false
interpolate facet corner attributes on generated intersections. Deactivates coplanar facets simplification if set.
Thanks for the quick reply!
That's what I suspected, but I couldn't find merge
.
I've updated my function (will update graphite as well later) but still cannot make it work.
Here's the code:
def gompy_merge():
scene_graph = gom.create(classname='OGF::SceneGraph', interpreter=gom)
scene_graph.clear()
faces = [scene_graph.load_object(f"/tmp/cube_face_{i}.obj") for i in range(6)]
faces[0].I.Mesh.merge(faces[2])
faces[0].I.Surface.merge_vertices()
ps.init()
ps.register_surface_mesh(
"union",
np.asarray(faces[0].I.Editor.find_attribute('vertices.point')),
np.asarray(faces[0].I.Editor.get_triangles()),
)
ps.show()
If I run help(faces[0].I.Mesh)
I get:
Help on Object:
<graphite.Object object>
OGF::MeshGrobMeshCommands
Commands that manipulate the mesh in a MeshGrob
while dir(faces[0].I.Mesh)
gives me:
['append',
'chrono',
'copy',
'disable_signals',
'disable_slots',
'disconnect',
'display_statistics',
'display_topology',
'enable_signals',
'enable_slots',
'gather',
'grob',
'meta_class',
'nb_elements',
'normalize_mesh',
'normalize_mesh_box',
'remove_isolated_vertices',
'remove_mesh_elements',
'set_properties',
'set_property',
'signals_enabled',
'slots_enabled',
'string_id']
so it looks I'm looking in the wrong place :sweat_smile:
If I define S = faces[0].I.Surface
I can see merge_vertices
but not just merge
['bake_colors',
'bake_normals',
'bake_texture',
'chrono',
'compute_boolean_operation',
'compute_difference',
'compute_intersection',
'compute_union',
'decimate',
'disable_signals',
'disable_slots',
'disconnect',
'enable_signals',
'enable_slots',
'expand_border',
'fill_holes',
'fix_facets_orientation',
'get_charts',
'grob',
'intersect',
'make_texture_atlas',
'merge_vertices',
'meta_class',
'nb_elements',
'pack_texture_space',
'parameterize_chart',
'remesh_feature_sensitive',
'remesh_quad_dominant',
'remesh_smooth',
'remove_charts',
'remove_invisible_facets',
'repair_surface',
'segment',
'set_properties',
'set_property',
'signals_enabled',
'slots_enabled',
'smooth',
'split_catmull_clark',
'split_quads',
'split_triangles',
'string_id',
'tessellate_facets',
'triangulate',
'triangulate_center_vertex',
'unglue_charts',
'unglue_sharp_edges']
It is S.I.Mesh.merge(...)
, not S.I.Surface.merge(...)
. If you do not have merge
in S.I.Mesh
maybe your Graphite is not up to date (added it recently).
Oooo, I'm stupid ! It is S.I.Mesh.append(T)
, not merge
, my bad !!!
BTW, I have just committed a gom.search("string to search")
feature, it searches all classes and all functions of Graphite and prints everything that contains the string to search
as a substring:
Type "help", "copyright", "credits" or "license" for more information.
>>> import gompy
o-[ModuleMgr ] Loading module: luagrob
o-[ModuleMgr ] Loading module: mesh
o-[ModuleMgr ] Loading module: voxel
o-[ModuleMgr ] Loading module: Experiment
o-[ModuleMgr ] Loading module: RayTracing
o-[ModuleMgr ] Loading module: WarpDrive
>>> gom.search("merge")
o-[GOM ] gom.meta_types.OGF.MeshGrobSurfaceCommands.merge_vertices
>>> gom.search("append")
gom.meta_types.OGF.CompositeGrob.append
gom.meta_types.OGF.Grob.append
gom.meta_types.OGF.Interpreter.append_dynamic_libraries_path
gom.meta_types.OGF.LuaGrob.append
gom.meta_types.OGF.LuaInterpreter.append_dynamic_libraries_path
gom.meta_types.OGF.MeshGrob.append
gom.meta_types.OGF.MeshGrobMeshCommands.append
gom.meta_types.OGF.MeshGrobTransportCommands.append_points
gom.meta_types.OGF.PythonInterpreter.append_dynamic_libraries_path
gom.meta_types.OGF.SceneGraph.append
gom.meta_types.OGF.VoxelGrob.append
>>> gom.search("SceneGraph")
gom.meta_types.OGF.SceneGraph
gom.meta_types.OGF.SceneGraphCommands
gom.meta_types.OGF.SceneGraphSceneCommands
gom.meta_types.OGF.SceneGraphShaderManager
gom.meta_types.OGF.SceneGraphToolsManager
No worries! I was wondering what was wrong after updating Graphite.. Now it works, thanks!
One more question: is merge_vertices
actually needed or does it happen automatically when calling append
? I updated my function and it seems there are no duplicate vertices after all the operations
def gompy_append():
scene_graph = gom.create(classname='OGF::SceneGraph', interpreter=gom)
scene_graph.clear()
faces = [scene_graph.load_object(f"/tmp/cube_face_{i}.obj") for i in range(6)]
for i in range(1, 4):
faces[0].I.Mesh.append(faces[i])
vertices = np.asarray(faces[0].I.Editor.find_attribute('vertices.point'))
print(f"{len(vertices)} vertices before merging")
faces[0].I.Surface.merge_vertices()
vertices = np.asarray(faces[0].I.Editor.find_attribute('vertices.point'))
print(f"{len(vertices)} vertices after merging")
ps.init()
ps.register_surface_mesh(
"union",
np.asarray(faces[0].I.Editor.find_attribute('vertices.point')),
np.asarray(faces[0].I.Editor.get_triangles()),
)
ps.show()
Yes, I confirm, append()
calls mesh_repair()
that merges vertices and deletes duplicated faces. I can add an option to deactivate it if need be.
Personally I don't need it. Thanks again for all the help!
Hello! I'm Nico_Campolongo from Twitter, decided to move my issues here as it might be easier to track and expand on them :smile:
I'm now trying to compute the union between two meshes, but I don't know if I'm doing something wrong or it's just supposed to work like it is now. I have some meshes (coming from FreeCAD, but it shouldn't matter) and would like to compute their union. Below you can find an example with 2 faces of a cube. If I visualize the faces I can see they're touching (I also double checked the points manually), but their union is empty. Is this the intended behaviour? How is the union defined?
Here's the code:
I cannot attach the obj files, I'll post them directly below:
and: