4
$\begingroup$

I am trying to make a python script that creates a 3-d graph and automatically puts certain edges in a freestyle line group. So far I am able to create a surface with the code

import bpy
from bpy.types import Operator
from bpy.props import FloatVectorProperty
from bpy_extras.object_utils import AddObjectHelper, object_data_add
from mathutils import Vector
import bpy
import bmesh
import numpy as np


xmin,xmax,ymin,ymax = -3,3,-3,3
N = 30

def f(x,y):
    return (np.sin(2*x)+np.sin(2*y))/2

verts = [Vector((x,y,f(x,y))) for y in np.linspace(ymin, ymax, N) for x in np.linspace(xmin, xmax, N)]
faces = [(i+j*N, i+1+j*N, i+1+(j+1)*N, i+(j+1)*N) for i in range(N-1) for j in range(N-1)]

mesh = bpy.data.meshes.new(name="New Object Mesh")
mesh.from_pydata(verts, [], faces)

mesh.update(calc_edges=True) 

obj = bpy.data.objects.new('new object', mesh)
obj.location = Vector([0,0,0])
scene = bpy.context.scene
scene.objects.link(obj)
scene.objects.active = obj
obj.select = True

I would like every other line of edges to be marked as a freestyle edge. By hand, I would go to edit mode > edges, alt+click on every other edge (to select the whole line of edges) and then do a "Mark Freestyle Edge". However, I would like my script to automatically mark the edges when the mesh is created.

Below is a picture with every other row of edges selected. enter image description here

$\endgroup$
4
  • $\begingroup$ Nice script. Could you please provide an image of the selection, ( bit confused by "every other edge") and result desired. (even if it's for N = 5) $\endgroup$
    – batFINGER
    Commented Nov 16, 2016 at 16:47
  • $\begingroup$ @batFINGER Thanks :-). I've added a picture. My end goal is actually to mark edges whose vertices lie near an integer, but if I can figure out how to mark edges from python at all, I think I can figure out how to do the rest... $\endgroup$ Commented Nov 17, 2016 at 3:42
  • 1
    $\begingroup$ I think you are looking for object.data.edges[0].use_freestyle_mark $\endgroup$
    – sambler
    Commented Nov 17, 2016 at 6:03
  • 1
    $\begingroup$ @sambler yeah that was the easy bit, got a bit stuck on how to select edges to mark. Think there should be a quick way to do this with edge indexes, but it wasn't jumping out at me. $\endgroup$
    – batFINGER
    Commented Nov 17, 2016 at 7:31

1 Answer 1

3
$\begingroup$

To mark a freestyle edge use MeshEdge.use_freestyle_mark

Here is some pretty ugly demo code to select every second line of edges in the x direction, that works because mesh is aligned x, y.

import bpy
import bmesh
from mathutils import Vector

context = bpy.context
mesh = context.object.data
N = 30
TOL = 0.0001

# clear all freestyle mark edges

for e in mesh.edges:
    e.use_freestyle_mark = False

def edge_by_value(e, axis, value):
    v1, v2 = e.verts
    return getattr(v1.co, axis) == getattr(v2.co, axis) and abs(getattr(v2.co, axis) - value ) < TOL

bm = bmesh.new()
bm.from_mesh(mesh)
bm.edges.ensure_lookup_table()

x = -3
while x < 3:

    edges = [e for e in bm.edges if edge_by_value(e, "x", x)]
    print(x, len(edges))
    for e in edges:
        mesh.edges[e.index].use_freestyle_mark = True
        mesh.edges[e.index].select = True # selected 
    # every second edge
    x += 2 * 6 / (N - 1)

mesh.update()

Running with this line of code

    edges = [e for e in bm.edges if edge_by_value(e, "x", x) 
               or edge_by_value(e, "y", x)]

enter image description here

Probably a better approach is: if you know the index order of the edges, would be using row/col integer modulus and div on the edge index.

$\endgroup$

You must log in to answer this question.

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