-
-
Save zeffii/686b6a5482bf8a6f49df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import bgl | |
import blf | |
import bmesh | |
from mathutils import Vector, Matrix | |
from collections import defaultdict | |
import sys | |
from sverchok.utils import ( | |
sv_bmesh_utils, | |
csg_core, | |
csg_geom | |
) | |
from sverchok.utils.csg_core import CSG | |
from sverchok.utils.sv_bmesh_utils import ( | |
pydata_from_bmesh, | |
bmesh_from_pydata | |
) | |
Scene = bpy.types.Scene | |
def new_obj(bm, named_object, named_mesh): | |
me = bpy.data.meshes.new(named_mesh) | |
bm.to_mesh(me) | |
bm.free() | |
scene = bpy.context.scene | |
obj = bpy.data.objects.new(named_object, me) | |
scene.objects.link(obj) | |
return obj | |
def generate_draw_geometry(caller, context): | |
bm = bmesh.new() | |
obj = bpy.context.active_object | |
me = obj.data | |
bm.from_mesh(me) | |
original_face = bm.faces.active | |
verts = [v.co.copy() for v in original_face.verts] | |
face_normal = original_face.normal.copy() | |
bm.free() | |
del bm | |
return verts, face_normal, obj.matrix_world.copy() | |
def generate_boolean_geom(verts, normal, scalar): | |
bm = bmesh.new() | |
final_verts = [] | |
num_verts = len(verts) | |
faces = [] | |
face1 = [] | |
face2 = [] | |
ftwix = [] | |
for idx, v in enumerate(verts): | |
final_verts.append(v) | |
face1.append(idx) | |
for idx, v in enumerate(verts, num_verts): | |
final_verts.append(v + (normal * scalar)) | |
face2.append(idx) | |
for idx, _ in enumerate(verts): | |
idx_1 = idx | |
idx_2 = (idx + 1) % num_verts | |
idx_3 = ((idx + 1) % num_verts) + num_verts | |
idx_4 = idx + num_verts | |
ftwix.append([idx_1, idx_2, idx_3, idx_4]) | |
faces.append(face1) | |
faces.append(face2) | |
faces.extend(ftwix) | |
return final_verts, faces | |
def generate_result(VA, PA, VB, PB): | |
a = CSG.Obj_from_pydata(VA, PA) | |
b = CSG.Obj_from_pydata(VB, PB) | |
recursionlimit = sys.getrecursionlimit() | |
sys.setrecursionlimit(10000) | |
try: | |
# polygons = a.union(b).toPolygons() | |
polygons = a.intersect(b).toPolygons() | |
# polygons = a.subtract(b).toPolygons() | |
except RuntimeError as e: | |
raise RuntimeError(e) | |
sys.setrecursionlimit(recursionlimit) | |
faces = [] | |
vertices = [] | |
for polygon in polygons: | |
indices = [] | |
for v in polygon.vertices: | |
pos = [v.pos.x, v.pos.y, v.pos.z] | |
if not (pos in vertices): | |
vertices.append(pos) | |
index = vertices.index(pos) | |
indices.append(index) | |
faces.append(indices) | |
return vertices, faces | |
def draw_callback_px(self, context, res): | |
verts, fnorm, fmatrix = res | |
scn = context.scene | |
scalar = scn.BGL_OFFSET_SCALAR | |
# 50% alpha, 2 pixel width line | |
bgl.glEnable(bgl.GL_BLEND) | |
bgl.glLineWidth(context.scene.BGL_DEMO_PROP_THICKNESS) | |
bgl.glColor4f(0.8, 0.3, 0.9, 1.0) | |
bgl.glBegin(bgl.GL_LINE_LOOP) | |
for vert in verts: | |
co = fmatrix * (vert + (fnorm * scalar)) | |
bgl.glVertex3f(*co) | |
bgl.glEnd() | |
# restore opengl defaults | |
bgl.glLineWidth(1) | |
bgl.glDisable(bgl.GL_BLEND) | |
bgl.glColor4f(0.0, 0.0, 0.0, 1.0) | |
class ModalDrawOperator(bpy.types.Operator): | |
bl_idname = "view3d.bgl_demo_modal_operator" | |
bl_label = "Simple Modal View3D Operator" | |
def modal(self, context, event): | |
context.area.tag_redraw() | |
scn = context.scene | |
if event.type in {'MIDDLEMOUSE'}: | |
return {'RUNNING_MODAL'} | |
if event.type in {'RIGHTMOUSE', 'ESC'}: | |
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') | |
return {'CANCELLED'} | |
if event.type in {'RET'}: | |
scalar = scn.BGL_OFFSET_SCALAR | |
VB, PB = generate_boolean_geom(self.verts, self.normal, scalar) # extract this | |
if False: | |
bm = bmesh_from_pydata(VB, [], PB) | |
new_obj(bm, "ExtractObject", "Extract_mesh") | |
obj = bpy.context.active_object | |
me = obj.data | |
bm = bmesh.new() | |
bm.from_mesh(me) # from this | |
VA, _, PA = pydata_from_bmesh(bm) | |
bm.free() | |
v, f = generate_result(VA, PA, VB, PB) | |
bm = bmesh_from_pydata(v, [], f) | |
bm.to_mesh(me) | |
bm.free() # free and prevent further access | |
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') | |
return {'FINISHED'} | |
return {'PASS_THROUGH'} | |
def invoke(self, context, event): | |
if context.area.type == 'VIEW_3D': | |
scn = context.scene | |
scn.BGL_OFFSET_SCALAR = 0.0 | |
scn.BGL_DEMO_PROP_THICKNESS = 5 | |
res = generate_draw_geometry(self, context) | |
self.verts = res[0] | |
self.normal = res[1] | |
self.scalar = res[2] | |
args = (self, context, res) | |
draw_handler_add = bpy.types.SpaceView3D.draw_handler_add | |
self._handle = draw_handler_add( | |
draw_callback_px, args, 'WINDOW', 'POST_VIEW') | |
bpy.ops.object.mode_set(mode='OBJECT') | |
context.active_object.show_wire = True | |
context.active_object.show_all_edges = True | |
context.window_manager.modal_handler_add(self) | |
return {'RUNNING_MODAL'} | |
else: | |
self.report({'WARNING'}, "View3D not found, cannot run operator") | |
return {'CANCELLED'} | |
class HelloWorldPanel(bpy.types.Panel): | |
"""Creates a Panel in the Object properties window""" | |
bl_label = "Hello World Panel" | |
bl_idname = "OBJECT_PT_hello" | |
bl_space_type = 'VIEW_3D' | |
bl_region_type = 'UI' | |
# bl_context = "object" | |
def draw(self, context): | |
layout = self.layout | |
col = layout.column() | |
col.prop(context.scene, 'BGL_DEMO_PROP_THICKNESS', text='thickness') | |
col.prop(context.scene, 'BGL_OFFSET_SCALAR', text='amount') | |
col.operator("view3d.bgl_demo_modal_operator") | |
def register(): | |
Scene.BGL_DEMO_PROP_THICKNESS = bpy.props.IntProperty(default=1, max=5) | |
Scene.BGL_OFFSET_SCALAR = bpy.props.FloatProperty( | |
min=-5.0, max=5.0, default=0.0) | |
bpy.utils.register_class(HelloWorldPanel) | |
bpy.utils.register_class(ModalDrawOperator) | |
def unregister(): | |
bpy.utils.unregister_class(HelloWorldPanel) | |
bpy.utils.unregister_class(ModalDrawOperator) | |
del Scene.BGL_OFFSET_SCALAR | |
del Scene.BGL_DEMO_PROP_THICKNESS | |
if __name__ == "__main__": | |
register() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment