0

In order to get proper right angles I was advised to use geometry nodes in my python script. Having zero experience with geometry nodes at all, what kind of geometry node do you recommend to replace the current skin modifier approach?

screenshot

import bpy
vertices=[[0,0,0],[0,0,1],[0,1,1]]
edges=[[0,1],[1,2]]
faces = []

name = "my_bmesh" mesh = bpy.data.meshes.new(name) obj = bpy.data.objects.new(name, mesh)

coll = bpy.data.collections.get("Collection") coll.objects.link(obj) bpy.context.view_layer.objects.active = obj mesh.from_pydata(vertices, edges, faces)

Add skin modifier

mod_skin = obj.modifiers.new('Skin', 'SKIN')

Add radius

dim = (0.3, 0.3)

for v in obj.data.skin_vertices[0].data: v.radius = dim

jjk
  • 980
  • 4
  • 18

1 Answers1

1

This is my best attempt using python and not using geo-nodes: if you create two separate meshes and the combine them by either using a boolean union modifier or by simply joining them together, the resulting mesh contains the right angles. Just un-triple-quote which ever option you prefer.

import bpy

vertices=[[0,0,1],[0,1,1]] edges=[[0,1]] faces = []

name = "my_bmesh" mesh = bpy.data.meshes.new(name) obj1 = bpy.data.objects.new(name, mesh)

coll = bpy.data.collections.get("Collection") coll.objects.link(obj1) bpy.context.view_layer.objects.active = obj1 mesh.from_pydata(vertices, edges, faces)

dim = (0.3, 0.3)

vertices=[[0,0,0],[0,0,1 + dim[0]]] edges=[[0, 1]] faces = []

name = "my_bmesh" mesh = bpy.data.meshes.new(name) obj2 = bpy.data.objects.new(name, mesh)

coll.objects.link(obj2) bpy.context.view_layer.objects.active = obj2 mesh.from_pydata(vertices, edges, faces)

Add skin modifier

mod_skin = obj1.modifiers.new('Skin', 'SKIN')

Add radius

for v in obj1.data.skin_vertices[0].data: v.radius = dim

mod_skin = obj2.modifiers.new('Skin', 'SKIN')

for v in obj2.data.skin_vertices[0].data: v.radius = dim

OPTION 1 --- BOOLEAN ROUTE (NO INNER GEOMETRY)

""" bpy.ops.object.modifier_add(type='BOOLEAN') bool = bpy.context.object.modifiers["Boolean"] bool.object = obj1 bool.operation = 'UNION'

bpy.context.view_layer.objects.active = obj1 bpy.ops.object.modifier_apply(modifier="Skin") bpy.context.view_layer.objects.active = obj2 bpy.ops.object.modifier_apply(modifier="Skin") bpy.ops.object.modifier_apply(modifier="Boolean") bpy.data.objects.remove(obj1) """

OPTION 2 --- JOIN ROUTE (CONTAINS INNER GEOMETRY)

""" obj1.select_set(True) obj2.select_set(True) bpy.ops.object.join()

can uncomment the following line if you only want the surrounding mesh

#bpy.ops.object.modifier_apply(modifier="Skin") """

If you want to go the geometry node route, this is the best node set-up I could come up with:

enter image description here

On top of the geometry nodes, be sure to add the solidify modifier as follows

enter image description here

Here's the geometry nodes script:

import bpy

vertices=[[0,0,0],[0,0,1],[0,1,1]] edges=[[0,1],[1,2]] faces = []

name = "my_bmesh" mesh = bpy.data.meshes.new(name) obj = bpy.data.objects.new(name, mesh)

coll = bpy.data.collections.get("Collection") coll.objects.link(obj) bpy.context.view_layer.objects.active = obj mesh.from_pydata(vertices, edges, faces)

add GeometryNodes modifier

bpy.ops.object.modifier_add(type="NODES")

bpy.ops.node.new_geometry_node_group_assign()

access active object node_group

node_group = bpy.context.object.modifiers["GeometryNodes"].node_group

add socket

inputs = node_group.inputs

add nodes

nodes = node_group.nodes mesh_to_curve = nodes.new(type = "GeometryNodeMeshToCurve") mesh_to_curve .location.x -= 150 mesh_to_curve .location.y -= 0

curve_to_mesh = nodes.new(type="GeometryNodeCurveToMesh")

curve_to_mesh.location.x += 20 curve_to_mesh.location.y += 0

bez = nodes.new(type="GeometryNodeCurvePrimitiveBezierSegment") bez.location.x += -150 bez.location.y -= 150

bez.inputs[1].default_value[0] = .3 bez.inputs[2].default_value[0] = 0 bez.inputs[2].default_value[1] = 0 bez.inputs[4].default_value[0] = -.3

connect

links = node_group.links

links.new(nodes["Group Input"].outputs["Geometry"], mesh_to_curve.inputs["Mesh"]) links.new(mesh_to_curve.outputs["Curve"], curve_to_mesh.inputs["Curve"]) links.new(curve_to_mesh.outputs["Mesh"], nodes["Group Output"].inputs["Geometry"]) links.new(bez.outputs["Curve"], curve_to_mesh.inputs["Profile Curve"])

bpy.ops.object.modifier_add(type='SOLIDIFY') solidify = bpy.context.object.modifiers["Solidify"] solidify.thickness = 0.6 solidify.use_even_offset = True solidify.offset = 0

Also, for this geometry nodes route, if you don't like the shading\smoothness, you can apply the geo-nodes and then auto-smooth the mesh or you can apply a Remesh modifier and set it to sharp or you can bump up the resolution of the bezier segment

Adam Swearingen
  • 1,160
  • 4
  • 12