Closed snovvfall closed 8 years ago
I made more or less stable and predictable solution. But this is terrible. And it only works for meshes made of vertices with Z coordinate 0. The Script node removes faces which have vertices with Z = 0. But it should be fine for the project I need all this madness for. See the magic: https://drive.google.com/file/d/0B3S8JZs3SIP4c1MxdHd1WTVjUGM/view?usp=sharing Blender itself should have good algorithm for dealing with this kind of situations, but I need faces to be created in Sverchok.
so, it was in plans - to create node to make mesh, but in blender there is no such command, you cannot make polygons in complex meshes. task of meshing point cloud this is: http://download.autodesk.com/global/docs/softimage2013/en_us/userguide/index.html?url=files/poly_topomod_MeshingPointCloudsandOtherThings.htm,topicNumber=d30e123376
but it takes ugly result because of ignoring edges, so current approach has to be improved or to find something better.
Fill Hole works, the bug is actually in triangulate. That the the output from fill hole shows incorrectly is due to that the option ngon tesselate has to be set to show concave n-gons correctly. This perhaps should be on by default @zeffii can fill explain that I guess. http://nikitron.cc.ua/sverch/html/nodes/viz/viewer_draw.html
However I can't replicate it using the console so it hard to make a proper bug report since it doesn't seem like a bmesh bug The below works like it should. Which is what the above nodes should do (with a lot of extra work.) With Plane in edit mode
bm=bmesh.from_edit_mesh(D.meshes['Plane'])
bmesh.ops.holes_fill(bm, edges=bm.edges[:])
bmesh.ops.triangulate(bm, faces=bm.faces[:])
bmesh.update_edit_mesh(D.meshes['Plane'])
I had time to look at it, and this scenario is exactly why ngon tesselation feature was added to the side panel options (draw_buttons_ext) of the ViewerDrawMK2 node. NGon tesselation was a way to get around the issue of drawing complex irregular polygons. Something we don't need very often, but annoying when we couldn't draw them correctly.
If my memory serves me correctly, the reason ngon-tesselation is not on by default is because it's extra computation that only needs to happen in special cases. The fact that I (or most of the team) almost never need to use it, is a good indication that this is a sane default.
The error that appears is after the triangulate node and is a very strange error.
The error was misdiagnosed as being caused by Fill Holes due to the rendering issue With concave. The real error in this cases is the triangulate node that does something very strange that does not seem to be happen when using the bmesh module directly in the console for the same geometry.
Suggesting a difference between the bmesh.ops.triangulate
(on a collection of polygons) and mathutils.geometry.tessellate_polygon
(on per polygon base, as this is used by ViewerDrawMK2)
i don't know :)
Original, from fill hole, and from triangulate.
Something goes wrong in triangulate. Don't know what though.
This is the input geometry.
BMesh example, everything works correctly.
import bmesh
bm = bmesh.new()
bm.from_mesh(bpy.data.meshes["Plane"])
bmesh.ops.holes_fill(bm, edges=bm.edges)
bmesh.ops.triangulate(bm, faces=bm.faces)
print([tuple(v.index for v in face.verts) for face in bm.faces])
--> [(4, 2, 3), (4, 0, 1), (4, 3, 5), (5, 0, 4)]
Which is the correct result.
However Triangulate node produces this however.
[(1, 2, 5), (1, 4, 2), (2, 3, 5), (5, 0, 1)]
Looking at the code I don't get what produces this result.
@ly29 , could you try bmesh.ops.triangulate(bm, verts=bm.verts, edges=bm.edges faces=bm.faces) (as it is written in triangulate.py) will it work correct?
I tried some different things with triangulate.py, but it looks like this, no?
res = bmesh.ops.triangulate(bm, faces=b_faces,
quad_method=int(self.quad_mode),
ngon_method=int(self.ngon_mode))
https://github.com/nortikin/sverchok/blob/master/nodes/modifier_change/triangulate.py#L102-L105
this is quite the bug @snovvfall , nice catch.
I confirm that this is Triangulate node which causes this issue. Viewer node ngons tesselation option returns the same result as Bmesh Viewer node, so it seems Bmesh Viewer node has tesselation always turned on or something like that. But I need to use Triangulate node sometimes to help me solve problems with CSG Boolean node. The headache got real when I was working on a project to calculate the area of ceiling inside rooms. Here is how monster tree looks now: 1) I create columns, walls, beams (hidden on the image), doors and windows. In each room I draw 2 lines on the floor level: one along monolith walls and columns and one along other walls (separators, thin, non-bearing). 2) Then I import these two objects, beams and objects responsible for doors and windows boolean. 3) Extrude both of them up, solidify just a tiny bit (0.02 mm) to make boolean work correctly, cut windows, doors and beams from them with boolean, calculate the area, divide the result by 2 to negate solidify influence and output the result as purple and red numbers on the image below. 4) Join these two objects into one, remove doubles (is there a single node to do all this by the way?). Remove all vertices except those on floor level Z = 0, remove doubles 1 cm, calculate edge length, output as green number. 5) Join two objects from the very beginning. Do the weird trick with fill holes I described in my previous comment in this discussion to prevent incorrect triangles, calculate the area, output as blue number. Also, IMPORTANT, the "RECALC NORMALS" node saves the day and greatly helps to prevent incorrect triangles in the future, see my previous comment. 6) Extrude up, cut beams (the most glitchy part here), remove vertices whose Z = 0, calculate the area and output as yellow number.
I would like to revisit this node, and perhaps include a safety-force option.
was this ever resolved or what?
Not as far as I know
Interestingly, and i'm not sure what this means:
vs
we can offer a slightly heavier homegrown triangluate much like what viewerDraw does, and call it HeavyTriangulate.
Hmmm, now I can't get to misbehave.
Okay now I get it (and remember), n-gons misbehave. But only via the node, not when using the bmesh interface itself.
it is almost like it ignores the faces for some reason and just triangulates the vertices....
# ##### 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
from bpy.props import IntProperty, EnumProperty, BoolProperty, FloatProperty
import mathutils
from mathutils.geometry import tessellate_polygon as tessellate
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, match_long_repeat, fullList
from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata, pydata_from_bmesh
class SvHeavyTriangulateNode(bpy.types.Node, SverchCustomTreeNode):
''' Triangulate mesh (Heavy)'''
bl_idname = 'SvHeavyTriangulateNode'
bl_label = 'Heavy Triangulate'
bl_icon = 'OUTLINER_OB_EMPTY'
def sv_init(self, context):
self.inputs.new('VerticesSocket', "Vertices", "Vertices")
self.inputs.new('StringsSocket', 'Polygons', 'Polygons')
self.outputs.new('VerticesSocket', 'Vertices')
self.outputs.new('StringsSocket', 'Edges')
self.outputs.new('StringsSocket', 'Polygons')
def process(self):
inputs = self.inputs
outputs = self.outputs
if not (inputs['Vertices'].is_linked and inputs['Polygons'].is_linked):
return
named = ['Vertices', 'Edges', 'Polygons']
if not (any(outputs[name].is_linked for name in named)):
return
vertices_s = inputs['Vertices'].sv_get(default=[[]])
faces_s = inputs['Polygons'].sv_get(default=[[]])
result_vertices = []
result_edges = []
result_faces = []
meshes = match_long_repeat([vertices_s, faces_s])
for vertices, faces in zip(*meshes):
bm = bmesh_from_pydata(vertices, [], faces)
new_edges = []
new_faces = []
for f in bm.faces:
coords = [v.co for v in f.verts]
indices = [v.index for v in f.verts]
if len(coords) > 3:
for pol in tessellate([coords]):
new_faces.append([indices[i] for i in pol])
else:
new_faces.append([v.index for v in f])
result_vertices.append([v.co[:] for v in bm.verts])
result_edges.append(new_edges)
result_faces.append(new_faces)
output_list = [
['Vertices', result_vertices],
['Edges', result_edges],
['Polygons', result_faces]
]
for output_name, output_data in output_list:
if outputs[output_name].is_linked:
outputs[output_name].sv_set(output_data)
def register():
bpy.utils.register_class(SvHeavyTriangulateNode)
def unregister():
bpy.utils.unregister_class(SvHeavyTriangulateNode)
This might be a bug in bmesh.ops.triangulate? none of the return geom seems sane.
Something goes wrong but if you call the op directly it seems to work as expected, if called from the python console.
If you can replicate it outside of node code there it is a bug with bmesh.ops.triangulate
, otherwise there is something we are missing.
I think it is the latter.
the difference between running from console and in a node is the console kind of requires there to be a Mesh structure, and that's the one thing we bypass by using bmesh_from_pydata. But why triangulate ops should behave differently is weird.
how about committing the slower version as SvTriangulateHeavy (we know it's potentially slow, but it works) ? or was this solved?
@zeffii it was not solved as i know. Please, commit
OK :)
github commit automatically closes an issue when you write 'fixes #somenumber`. Can leave closed for now until someone finds time to investigate
Ok, this problem makes me crazy. Spent three days trying to solve it with some sort of a workaround, but succeeded only by chance with some meshes. Problem is I cannot import normal mesh with or without triangulate modifier from Blender to Sverchok. In my case I need to import closed ngon consisting of only edges and make it a face right inside Sverchok. But "Fill Holes" returns incorrect result. On the picture below the figure should be with only vertical and horizontal lines, "L"-shaped.