Is it possible to create a BMesh polygon (BMFace) with holes via Python?
Use case. I need that for my addons that import geographical data. A polygon for Rome has a hole for Vatican City.
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It only takes a minute to sign up.
Sign up to join this communityPolygons in Mesh or BMesh aren't permitted to have holes in the sense of providing a perimeter and adding an internal part to subtract. This means considering alternatives.
But it will contain at least two duplicated vertices for that pathway between the cutout and the perimeter.
mesh.fill()
, which could take two given edge outlines and fill from the outer edges inwards. (will add script when I have time)mesh.fill()
for the general case: concave perimeter, multiple concave holes?
$\endgroup$
BMesh operator bmesh.ops.triangle_fill does the trick:
bmesh.ops.triangle_fill(bm, use_beauty=True, use_dissolve=False, edges=outer_and_inner_edges)
Here outer_and_inner_edges
is the list of BMesh edges (both outer and inner) that constitute the polygon with holes.
The operator will create a bunch of triangles that cover the polygon in question.
yes, is possible.. you need your vertices and faces data...
here a fast template, you only need to modify your vertices and face data:
this addon set a button in order to add some cube with hole:
bl_info = {
"name": "bmesh with holes",
"author": "Diego Quevedo",
"version": (1, 0),
"blender": (2, 7, 3),
"location": "View3D > Add > Mesh > bmesh",
"description": "Adds a new Mesh Object using bmesh",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Add Mesh"}
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
def add_object(self, context):
edges = []
verts = [(1.0, 0.9999999403953552, -1.0), (1.0, -1.0, -1.0), (-1.0000001192092896, -0.9999998211860657, -1.0), (-0.9999996423721313, 1.0000003576278687, -1.0), (-0.7993143200874329, 7.718172128079459e-07, -1.0), (-0.7839558124542236, -0.1559378057718277, -1.0), (-0.7384703755378723, -0.3058837354183197, -1.0), (-0.6646059155464172, -0.4440747797489166, -1.0), (-0.565200924873352, -0.5652002096176147, -1.0), (-0.44407564401626587, -0.6646053194999695, -1.0), (-0.3058846890926361, -0.7384699583053589, -1.0), (-0.15593880414962769, -0.7839556336402893, -1.0), (-2.6044966716654017e-07, -0.7993143200874329, -1.0), (0.1559382975101471, -0.7839557528495789, -1.0), (0.3058842122554779, -0.738470196723938, -1.0), (0.44407519698143005, -0.6646056175231934, -1.0), (0.5652005672454834, -0.5652005672454834, -1.0), (0.6646056175231934, -0.44407519698143005, -1.0), (0.7384701371192932, -0.3058842122554779, -1.0), (0.7839557528495789, -0.15593838691711426, -1.0), (0.7993143200874329, 6.034655086750718e-08, -1.0), (0.7839556932449341, 0.1559385061264038, -1.0), (0.7384701371192932, 0.30588433146476746, -1.0), (0.6646056175231934, 0.44407519698143005, -1.0), (0.5652005672454834, 0.5652005672454834, -1.0), (0.44407525658607483, 0.6646055579185486, -1.0), (0.30588436126708984, 0.7384701371192932, -1.0), (0.15593849122524261, 0.7839556932449341, -1.0), (0.0, 0.7993143200874329, -1.0), (-0.1559372842311859, 0.7839559316635132, -1.0), (-0.3058832585811615, 0.7384706139564514, -1.0), (-0.4440743327140808, 0.6646061539649963, -1.0), (-0.5651998519897461, 0.5652012825012207, -1.0), (-0.6646050214767456, 0.4440760612487793, -1.0), (-0.7384697794914246, 0.3058851659297943, -1.0), (-0.7839555740356445, 0.15593931078910828, -1.0), (1.0000004768371582, 0.999999463558197, 1.0), (-0.9999999403953552, 1.0, 1.0), (0.9999993443489075, -1.0000005960464478, 1.0), (-1.0000003576278687, -0.9999996423721313, 1.0), (-2.6044966716654017e-07, -0.7993143200874329, 1.0), (-0.15593880414962769, -0.7839556336402893, 1.0), (-0.3058846890926361, -0.7384699583053589, 1.0), (-0.44407564401626587, -0.6646053194999695, 1.0), (-0.565200924873352, -0.5652002096176147, 1.0), (-0.6646059155464172, -0.4440747797489166, 1.0), (-0.7384703755378723, -0.3058837354183197, 1.0), (-0.7839558124542236, -0.1559378057718277, 1.0), (-0.7993143200874329, 7.718172128079459e-07, 1.0), (-0.7839555740356445, 0.15593931078910828, 1.0), (-0.7384697794914246, 0.3058851659297943, 1.0), (-0.6646050214767456, 0.4440760612487793, 1.0), (-0.5651998519897461, 0.5652012825012207, 1.0), (-0.4440743327140808, 0.6646061539649963, 1.0), (-0.3058832585811615, 0.7384706139564514, 1.0), (-0.1559372842311859, 0.7839559316635132, 1.0), (0.0, 0.7993143200874329, 1.0), (0.15593849122524261, 0.7839556932449341, 1.0), (0.30588436126708984, 0.7384701371192932, 1.0), (0.44407525658607483, 0.6646055579185486, 1.0), (0.5652005672454834, 0.5652005672454834, 1.0), (0.6646056175231934, 0.44407519698143005, 1.0), (0.7384701371192932, 0.30588433146476746, 1.0), (0.7839556932449341, 0.1559385061264038, 1.0), (0.7993143200874329, 6.034655086750718e-08, 1.0), (0.7839557528495789, -0.15593838691711426, 1.0), (0.7384701371192932, -0.3058842122554779, 1.0), (0.6646056175231934, -0.44407519698143005, 1.0), (0.5652005672454834, -0.5652005672454834, 1.0), (0.44407519698143005, -0.6646056175231934, 1.0), (0.3058842122554779, -0.738470196723938, 1.0), (0.1559382975101471, -0.7839557528495789, 1.0)]
faces = [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), (0, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 4, 3), (36, 0, 3, 37), (0, 36, 38, 1), (1, 38, 39, 2), (2, 39, 37, 3), (36, 37, 39, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55), (36, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 40, 38), (28, 27, 57, 56), (29, 28, 56, 55), (27, 26, 58, 57), (30, 29, 55, 54), (26, 25, 59, 58), (31, 30, 54, 53), (25, 24, 60, 59), (32, 31, 53, 52), (24, 23, 61, 60), (33, 32, 52, 51), (23, 22, 62, 61), (34, 33, 51, 50), (22, 21, 63, 62), (35, 34, 50, 49), (21, 20, 64, 63), (4, 35, 49, 48), (20, 19, 65, 64), (5, 4, 48, 47), (19, 18, 66, 65), (6, 5, 47, 46), (18, 17, 67, 66), (7, 6, 46, 45), (17, 16, 68, 67), (8, 7, 45, 44), (16, 15, 69, 68), (9, 8, 44, 43), (15, 14, 70, 69), (10, 9, 43, 42), (14, 13, 71, 70), (11, 10, 42, 41), (13, 12, 40, 71), (12, 11, 41, 40)]
try:
mesh = bpy.data.meshes.new(name="New Object Mesh")
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
object_data_add(context, mesh, operator=self)
except:
print("error")
class OBJECT_OT_add_object(Operator, AddObjectHelper):
"""Create a new Mesh Object"""
bl_idname = "mesh.cube_hole"
bl_label = "Add Mesh Object"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
add_object(self, context)
return {'FINISHED'}
class OBJECT_OT_add_objectPanel(bpy.types.Panel):
#bl_category = "NN"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
#bl_context = "editmode"
bl_label = "ADD_OBJ"
@classmethod
def poll(cls, context):
return (context.mode == 'OBJECT' or context.mode == 'EDIT_MESH' )
def draw(self, context):
layout = self.layout
row = layout.row(align=True)
row.operator(OBJECT_OT_add_object.bl_idname) #THE OPERATOR
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()