Open ArpegorPSGH opened 2 years ago
CSG Boolean 2 node is not what you are looking for?
Well, it could be used to find intersection points by comparing the output vertices with the input vertices and retaining only the new ones, but it would be heavy calculations for something quite simple. Furthermore, it has a lot of limitations and is slow (according to documentation), and do not allow to merge meshes like Intersect (knife) does. So I really don't think it would be a good idea to use CSG Boolean 2. The node I am talking about would only need to find intersection points between each edge and all the polygons of the mesh(es), and optionally split edges and faces accordingly. I created a node tree to find intersection points, and it works fine, but it is quite slow as I used over 20 nodes as well as for each loops.
mesh.ops has intersect_boolean , not a bmesh.ops unfortunately.
unfortunately the mesh.ops doesn't return the matching topology indices that overlap between multiple objects., it just performs the intersection+union..
bpy.ops.mesh.intersect is what I was referring to. It is not difficult to code I believe, it is just that there is no way to do this efficiently currently. That's basically just edge/polygon intersections, or raycasting vertices along edges on mesh(es), limiting distance to edges lengths.
here's with appropriate hiding..
"""
>in iverts v
>in ifaces s
out overts v
out ofaces s
"""
shell_object_name = "bifida"
docstring = """
[ ] create shell object + mesh
[ ] select all geometry
[ ] set to edit mode
[ ] execute mesh.ops
[ ] set to object mode
[ ] get new mesh data
[ ] delete shell object
"""
for idx, (verts, faces) in enumerate(zip(iverts, ifaces)):
# for now skip all additional mesh input, to prove a point.
if idx > 0: continue
if shell_object_name in bpy.data.meshes:
data = bpy.data.meshes[shell_object_name]
data.clear_geometry()
obj = bpy.data.objects.get(shell_object_name)
else:
data = bpy.data.meshes.new(name=shell_object_name)
obj = bpy.data.objects.new(shell_object_name, data)
bpy.context.scene.collection.objects.link(obj)
obj.hide_viewport = False
obj.hide_render = False
bpy.ops.object.mode_set(mode='OBJECT')
data.from_pydata(verts, [], faces)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.intersect_boolean(operation='UNION', solver='EXACT',
use_swap=False, use_self=True, threshold=-.00006)
bpy.ops.object.mode_set(mode='OBJECT')
overts.append([v.co[:] for v in data.vertices])
ofaces.append([f.vertices[:] for f in data.polygons])
obj.hide_viewport = True
obj.hide_render = True
Well, what I am most interested in is getting intersection points, so using boolean is not best, I think knife is better. Furthermore, when sverchok get multi-threaded, using bpy.ops won't be possible whithin loops or multi-branch trees, that is why I try to limit any scripts using them to intial or final treatments of the trees.
you might want to look at the bvh
nodes, and consider cobbling together a prototype script.
bvh docs (Blender) bvh_overlap_polys.py
unfortunately the bvh seems to work only on verts+faces, so while it would speed up the scenario where you look for intersections of two polygon based meshes, we don't have a massively efficient way to do proximity based lookups on verts+edge combinations ( it's a bit of an iterative process comparing all edges,
also definitely look at the code behind the intersect edges
node , especially the imported functions. (https://github.com/nortikin/sverchok/blob/master/utils/geom_2d/intersections.py ,,etc)
I think it should be doable with raycasting, by taking each edge and raycasting one of its vertices along the edge direction, finding hit point on mesh, taking that as new start point, project again along edge direction, and so on until the opposite edge vertex is reached, then collect all hit points and return them. The process is also parallelizable on the edge level. However, I do not have much time to implement it as of now, and I am not confident in my ability to produce efficient code, so if anyone is willing to do it, great, otherwise, I have already a node tree performing that, although quite slowly, so I won't work on it anytime soon.
make a mockup nodetree, and show what the input looks like ( viewer draw ) and show what the desired node socket configuration is of the IntersectionNode, and show the output of that node ( stethoscopes + viewer draws.. ) that way there is no ambiguity about the behaviour. Use simplest input mesh. No guarantees, but the edges intersection
node is something i added to sverchok back in 2014, and it has had many upgrades.
You may be interested in this node: https://github.com/nortikin/sverchok/blob/master/docs/nodes/modifier_make/cut_object_by_surface.rst It is very limited, but in some cases it can help.
It is quite close from what I am looking for, however the limitation make it unusable for me, and I am looking for intersections both ways, not only from one mesh with another.
You're welcome to enhance it :)
I'll look into that when I have some time.
Merge Mesh 2D?
I need only the new vertices, and in a 3D context, so I think solving the limitation of Cut Object by Surface, and adding a socket containing the intersections found is the best way to go.
After reading the code, in fact there is no need for a new socket, just to solve the limitation. I already know how to find all the intersection points by modifying the code slightly, but generating cut faces and cut parts, especially the parts will be very complicated. If it is fine, I can modify only the part about finding the intersections in such a way that it works the same as now, and reduce the implementation limitation case to only when attempting to generate cut faces or cut parts. I found a strange part in the code, stating that : "Since raycast's ray is single-directioned, we have to check for intersections twice : from V1 to V2 and from V2 to V1." I dont' understand what is the point : if there is no intersection from vertex V2 to vertex V1, there cannot be an intersection from vertex V1 to vertex V2, right? I think I can also add an all triangle option, since raycast is used internally. Since it will be my first time contributing to sverchok and to a GitHub project in general, could you tell me how to go about working on the node, debugging it, testing it, and submitting it for merge?
If it is fine, I can modify only the part about finding the intersections in such a way that it works the same as now, and reduce the implementation limitation case to only when attempting to generate cut faces or cut parts.
Ok, you just have to maintain backwards compatibility. If your new code will give different results on existing setups, you have to make an option to switch new functionality off. Or maybe create an mk2 version of the node.
I dont' understand what is the point :
Correct, if there is an intersection from V1 to V2, then there cannot be an intersection from V2 to V1. But, if there is no intersection from V1 to V2, we still have to check for intersection from V2 to V1.
Since it will be my first time contributing to sverchok and to a GitHub project in general, could you tell me how to go about working on the node, debugging it, testing it, and submitting it for merge?
Refer to http://nortikin.github.io/sverchok/docs/contributing/contributing_to_sverchok.html :)
If you decide to make an mk2 version of the node:
You mean raycasting is influenced by front-side/back-side of face, it does not look only for a face, whatever its normal?
I do not remember exactly right now, but judging by code and comment - if you try to send a ray from "back" side of a face, you will not see intersection. But you're welcome to try, maybe I was wrong.
When I use the raycaster node, I can project onto back faces fine, so it seems strange. Well, it does not decrease node efficiency by much, just adds more volume to the code.
@portnov Okay, I finally found some time to work on this issue, and I tried to download the development version with the code there, but I got this error :
git@github.com: Permission denied (publickey).
Note that it is my first time using Git, I installed it specifically for contributing to Sverchok, so it may be a dumb error. I suspect that it has something to do with me skipping your instruction to "clone this repo on github", as I didn't understand it. Am I supposed to clone the repository directly on github? If yes, how? If no, does that mean I have to download it on my computer? But in that case, it wouldn't be consistent anymore with the code for installing the development version.
First you have to create a fork of this repo on github (see button at the top of this page), then you work with your repo,then you create a pull request, asking us to pull changes from your repo to ours. I suggest you to google for "Github Pull Request Howto", there ought to be plenty of them.
I forked only the master branch, is it alright?
Yes, you will create a pull request towards the master.
I forked, cloned to my machine, and checked out to create a new branch. Then I ran mkdir -p ~/.config/blender/3.2/scripts/addons/
while in my branch, then ln -s "C:/Program Files/Blender Foundation/sverchok" ~/.config/blender/3.2/scripts/addons/
, and everything went without error or warnings. However, when I went to Blender, nothing changed from the regular version, and when I modify the code of my local repo and reload the scripts, nothing changes on the node I'm working on.
However, I skipped "go to Blender preferences, locate Sverchok addon and enable it as usual.", as I don't really understand what it means : I have sverchok already enabled.
What worked however, was to modify code directly inside Blender with Node Edit Source Internally button, but it isn't really a proper way to work, I guess?
Probably in your installation (this may be windows-specific), your usual Sverchok installation is located in some another directory, not in ~/.config/blender/3.2/scripts/addons/
. You can probably check this out when you do "edit source internally" — where is the file located?
The idea is to replace your "standard" Sverchok installation directory with the directory which you cloned from github.
Yeah, the file is located in another place, that is why it didn't work.
There is a node to find self intersections of a wireframe (Intersect Edges), but none to find intersections between two meshes or self intersections. By intersection I mean it in the sense of the Intersect (knife) of Blender, i. e. to find all edge/face intersections, and return it as a list of points. Additionally, there could be the possibility to actually merge the two meshes or self-merge the mesh.