0

I would like to create a simple 3d shape from a list of vertices, so I wrote a Python script which subdivides a cube and uses the Shrinkwrap modifier.

After the shape is created, I would like to be able to select the faces and/or edges of the new shape. If I go into edit mode in the 3d view, I can select an entire face on the object I called "Final". However, if I look at the number of edges or faces in the Python console, I get a large number (in the case of my example, it says 96 faces). I am including an example using vertex points from a triangular prism, but I would like to do this with a polygon with an arbitrary number of vertices. I would like to be able to find the entire face for each of the sides of my object in Python.

import bpy
import bmesh
from mathutils import Vector,Euler
from bpy_extras.object_utils import AddObjectHelper, object_data_add

w = 2 h = 3 length = 4

verts = [ Vector((w/2,0,0)),Vector((-w/2,0,0)),Vector((-w/2,0,-h)), Vector((0,length,0)),Vector((w/2,0,-h)),Vector((0,length,-h))]

mesh = bpy.data.meshes.new(name="New Object Mesh") mesh.from_pydata(verts, [], []) objpoints=object_data_add(bpy.context, mesh) objsize=objpoints.dimensions bpy.ops.mesh.primitive_cube_add() objmod=bpy.context.active_object objmod.dimensions=[1.3objsize.x,1.3objsize.y,1.3*objsize.z] bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.subdivide(number_cuts=3) bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

wrapmod = objmod.modifiers.new(name='shapefrompoints', type='SHRINKWRAP') wrapmod.target = objpoints wrapmod.wrap_method = 'NEAREST_VERTEX'

apply the modifier so we have a real object

depsgraph = bpy.context.evaluated_depsgraph_get()

apply modifier using depsgraph (dependency graph

https://blender.stackexchange.com/questions/146559/how-do-i-get-a-mesh-data-block-with-modifiers-and-shape-keys-applied-in-blender

object_eval = objmod.evaluated_get(depsgraph) obj=bpy.data.objects.new("Final",object_eval.data.copy()) bpy.context.collection.objects.link(obj)

SJK
  • 169
  • 1
  • 7

1 Answers1

2

1.The object which is created "Final" has to be selected before applying the modifier. Hence added the following: objf=bpy.data.objects.new("Final",object_eval.data.copy()) bpy.context.collection.objects.link(objf) bpy.context.view_layer.objects.active = objf objf.select_set(True)

  1. To remove doubles the following lines are added: bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.remove_doubles() bpy.ops.object.mode_set(mode='OBJECT')

  2. Modifier has to me named for it to effect: bpy.ops.object.modifier_apply(modifier='shapefrompoints')

  3. To verify the result: print("No of vertices",len(objf.data.vertices)," No of edges =",len(objf.data.edges),"No of polygons",len(objf.data.polygons))

the above after running the full code gives: Info: Removed 50 vertice(s) No of vertices 6 No of edges = 9 No of polygons 5 which is correct for the triangular prism.

=============================== Full code given below:

 import bpy
 import bmesh
 from mathutils import Vector,Euler
 from bpy_extras.object_utils import AddObjectHelper, object_data_add

w = 2 h = 3 length = 4
verts = [ Vector((w/2,0,0)),Vector((-w/2,0,0)),Vector((-w/2,0,-h)), Vector((0,length,0)),Vector((w/2,0,-h)),Vector((0,length,-h))]

mesh = bpy.data.meshes.new(name="New Object Mesh") mesh.from_pydata(verts, [], []) objpoints=object_data_add(bpy.context, mesh) objsize=objpoints.dimensions

bpy.ops.mesh.primitive_cube_add() objmod=bpy.context.active_object objmod.dimensions=[1.3objsize.x,1.3objsize.y,1.3*objsize.z] bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.subdivide(number_cuts=2) bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

wrapmod = objmod.modifiers.new(name='shapefrompoints', type='SHRINKWRAP') wrapmod.target = objpoints wrapmod.wrap_method = 'NEAREST_VERTEX'

apply the modifier so we have a real object

depsgraph = bpy.context.evaluated_depsgraph_get()

apply modifier using depsgraph (dependency graph

https://blender.stackexchange.com/questions/146559/how-do-i-get-a-mesh-data-

block-with-modifiers-and-shape-keys-applied-in-blender object_eval = objmod.evaluated_get(depsgraph) objf=bpy.data.objects.new("Final",object_eval.data.copy()) bpy.context.collection.objects.link(objf) bpy.context.view_layer.objects.active = objf objf.select_set(True) bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.remove_doubles() bpy.ops.object.mode_set(mode='OBJECT')

bpy.ops.object.modifier_apply(modifier='shapefrompoints')

print("no of vertices",len(objf.data.vertices)," no of edges =",len(objf.data.edges),"no of polygons",len(objf.data.polygons))

vcleanall
  • 21
  • 2
  • Thank you. Your correction allows me to identify each of the sides of an arbitrary shape. Correctly using remove_doubles is the main part. However, if I understand modifiers correctly, I don't need to use both the dependency graph and modifier_apply., and the depsgraph method is more efficient. – SJK Aug 30 '21 at 15:20