1
$\begingroup$

I am looking for a way to convert a curve into a mesh with specified resolution via Python API. For example, a 100 m curve should be turned into a mesh where vertices are placed every 1 m along the curve, irrespective of the number or position of the original curve segments/control points. The type of the curve is not important, let's say it is a Nurbs path.

If there is no simple way to achieve that, is it possible to get coordinates of a point at a specified distance or percentage of length along the curve? (From here it should be possible to achieve the desired result using calc_length).

I am aware of tricks with constraints and animation, but perhaps it could be done in a more direct manner.

$\endgroup$
4
  • $\begingroup$ check out this answer here: blender.stackexchange.com/questions/93391/… this should help $\endgroup$
    – Chris
    Mar 29 at 19:08
  • $\begingroup$ What if the length of the curve is not divisible by specified length? Geometry Nodes have an option to do that (and dynamically creating a geonodes tree might be more performant than doing it in Python if the curve is to be divided to a lot of segments or if there's a lot of curves). $\endgroup$ Mar 29 at 19:15
  • $\begingroup$ The divisibility of the length of the curve is of no importance in my task. I can choose the length of the segment based on the total length, the requirement is only that the points are evenly spaced (which wouldn't be the case if I simply subdivided the segments of the original curve). And even this requirement can be relaxed a bit, i.e. if I have, say, 9 segments of 1 m each and the tenth is 0.95 m. I don't expect the number of segments to exceed 1-1.5 thousand, or let's say 10 thousand in the most extreme cases, and the number of curves is in single figures at most. $\endgroup$ Mar 30 at 5:48
  • $\begingroup$ Space operator from looptools github.com/sobotka/blender-addons/blob/master/mesh_looptools.py $\endgroup$
    – lemon
    Mar 30 at 14:37

1 Answer 1

1
$\begingroup$

This can be done in Geometry nodes easily:

You can create this geometry nodes tree and use it in Python, or you can create it dynamically in Python. I think it's reasonable, because finding out the position of the points is a computationally expensive process (basically trial-and-error), which multiplied by thousands of segments probably would end up too expensive in Python - meaning that the overhead of evaluating the depsgraph and the object is likely worth it.

from bpy import context as C, data as D

ob = C.object
mod = ob.modifiers.new(name="Temp geonodes modifier", type='NODES')
tree = D.node_groups.new("Temp geonodes tree", 'GeometryNodeTree')
tree.inputs.new('NodeSocketGeometry', 'Geometry')
tree.outputs.new('NodeSocketGeometry', 'Geometry')

node_in = tree.nodes.new(type='NodeGroupInput')
node_ctp = tree.nodes.new(type='GeometryNodeCurveToPoints')
node_ctp.mode = 'LENGTH'
node_ctp.inputs['Length'].default_value = 0.2
tree.links.new(node_in.outputs[0], node_ctp.inputs['Curve'])
node_ptv = tree.nodes.new(type='GeometryNodePointsToVertices')
tree.links.new(node_ctp.outputs['Points'], node_ptv.inputs['Points'])
node_out = tree.nodes.new(type='NodeGroupOutput')
tree.links.new(node_ptv.outputs['Mesh'], node_out.inputs[0])

mod.node_group = tree
dg = C.evaluated_depsgraph_get()
ev = C.object.evaluated_get(dg)
me = ev.to_mesh()
print("Coordinates:", *[v.co for v in me.vertices], sep="\n")
ob.modifiers.remove(mod)
D.node_groups.remove(tree)
$\endgroup$
2
  • $\begingroup$ Yes, I will have to construct depsgraph for other purposes anyway. As for the solution with geometry nodes, I am not yet sufficiently familiar with this feature, will have to look at it in more detail. Have always been more at home with plain old programming. Thanks! $\endgroup$ Mar 30 at 12:21
  • $\begingroup$ Using geonodes in Python is interesting, because Python is slow, while the implementation of geonodes is in C++. $\endgroup$ Mar 30 at 12:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .