|
|
@@ -1,157 +0,0 @@ |
|
|
import bpy |
|
|
|
|
|
from mathutils import Vector, Euler |
|
|
|
|
|
from math import pi |
|
|
|
|
|
import json |
|
|
|
|
|
import os |
|
|
|
|
|
import bpy_extras |
|
|
|
|
|
import bmesh |
|
|
|
|
|
import time |
|
|
|
|
|
|
|
|
|
|
|
class ModalTimerOperator(bpy.types.Operator): |
|
|
|
|
|
"""Operator which runs its self from a timer""" |
|
|
|
|
|
bl_idname = "wm.modal_timer_operator" |
|
|
|
|
|
bl_label = "Modal Timer Operator" |
|
|
|
|
|
|
|
|
|
|
|
_timer = None |
|
|
|
|
|
index = 0 |
|
|
|
|
|
|
|
|
|
|
|
def menu_func(self, context): |
|
|
|
|
|
self.layout.operator(ModalTimerOperator.bl_idname) |
|
|
|
|
|
|
|
|
|
|
|
def modal(self, context, event): |
|
|
|
|
|
scene = context.scene |
|
|
|
|
|
if self.index >= len(self.sides): |
|
|
|
|
|
self.cancel(context) |
|
|
|
|
|
return {'CANCELLED'} |
|
|
|
|
|
|
|
|
|
|
|
if event.type == 'TIMER': |
|
|
|
|
|
print("HOLY COW!!!") |
|
|
|
|
|
self.capture(self.sides[self.index]) |
|
|
|
|
|
self.index += 1 |
|
|
|
|
|
if self.index < len(self.sides): |
|
|
|
|
|
self.position_camera(self.sides[self.index]) |
|
|
|
|
|
else: |
|
|
|
|
|
self.export_data() |
|
|
|
|
|
|
|
|
|
|
|
return {'PASS_THROUGH'} |
|
|
|
|
|
|
|
|
|
|
|
def execute(self, context): |
|
|
|
|
|
print("execute!") |
|
|
|
|
|
self.c = bpy.data.objects["cam"] |
|
|
|
|
|
self.scene = bpy.context.scene |
|
|
|
|
|
selected = bpy.context.selected_objects[0] |
|
|
|
|
|
|
|
|
|
|
|
bpy.ops.object.mode_set(mode="OBJECT") |
|
|
|
|
|
bpy.ops.object.transform_apply( rotation = True ) |
|
|
|
|
|
|
|
|
|
|
|
self.data = {} |
|
|
|
|
|
|
|
|
|
|
|
self.b = selected |
|
|
|
|
|
|
|
|
|
|
|
FRONT = [0, 1, 2, "Front"] |
|
|
|
|
|
SIDE = [1, 1, 2, "Side"] |
|
|
|
|
|
TOP = [0, 0, 1, "Top"] |
|
|
|
|
|
ANGLED = [0.5, 1, 2, "Angled"] |
|
|
|
|
|
|
|
|
|
|
|
self.sides = [FRONT, SIDE, TOP, ANGLED] |
|
|
|
|
|
|
|
|
|
|
|
path = "/tmp/macrovision/" |
|
|
|
|
|
|
|
|
|
|
|
media_path = "/home/crux/furry/macrovision/media/" |
|
|
|
|
|
media_folder = "buildings/Houses/" |
|
|
|
|
|
|
|
|
|
|
|
os.makedirs(path, exist_ok=True) |
|
|
|
|
|
os.makedirs(os.path.join(media_path, media_folder), exist_ok=True) |
|
|
|
|
|
wm = context.window_manager |
|
|
|
|
|
self._timer = wm.event_timer_add(0.25, window=context.window) |
|
|
|
|
|
wm.modal_handler_add(self) |
|
|
|
|
|
self.position_camera(self.sides[self.index]) |
|
|
|
|
|
return {'RUNNING_MODAL'} |
|
|
|
|
|
|
|
|
|
|
|
def cancel(self, context): |
|
|
|
|
|
wm = context.window_manager |
|
|
|
|
|
wm.event_timer_remove(self._timer) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getView3dAreaAndRegion(self, context): |
|
|
|
|
|
for area in context.screen.areas: |
|
|
|
|
|
if area.type == "VIEW_3D": |
|
|
|
|
|
for region in area.regions: |
|
|
|
|
|
if region.type == "WINDOW": |
|
|
|
|
|
print("Found WINDOW") |
|
|
|
|
|
return area, region |
|
|
|
|
|
|
|
|
|
|
|
def select_border(self, context, view3dAreaAndRegion=None, extend=True): |
|
|
|
|
|
if not view3dAreaAndRegion: |
|
|
|
|
|
view3dAreaAndRegion = self.getView3dAreaAndRegion(context) |
|
|
|
|
|
print(view3dAreaAndRegion) |
|
|
|
|
|
view3dArea, view3dRegion = view3dAreaAndRegion |
|
|
|
|
|
override = context.copy() |
|
|
|
|
|
override['area'] = view3dArea |
|
|
|
|
|
override['region'] = view3dRegion |
|
|
|
|
|
bpy.ops.view3d.select_box(override,xmin=0,xmax=view3dArea.width,ymin=0,ymax=view3dArea.height,mode='SET') |
|
|
|
|
|
|
|
|
|
|
|
def position_camera(self, angles): |
|
|
|
|
|
bpy.ops.object.mode_set(mode="OBJECT") |
|
|
|
|
|
local_bbox_center = 0.125 * sum((Vector(box) for box in self.b.bound_box), Vector()) |
|
|
|
|
|
global_bbox_center = self.b.matrix_world @ local_bbox_center |
|
|
|
|
|
self.c.data.ortho_scale = max(self.b.dimensions) * 1.3 |
|
|
|
|
|
self.c.location = global_bbox_center |
|
|
|
|
|
self.c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2]) |
|
|
|
|
|
rot = self.c.rotation_euler.to_matrix() |
|
|
|
|
|
rot.invert() |
|
|
|
|
|
self.c.location = self.c.location + Vector([0, 0, 100]) @ rot |
|
|
|
|
|
self.data[angles[3]] = self.b.dimensions[angles[2]] |
|
|
|
|
|
|
|
|
|
|
|
def capture(self, angles): |
|
|
|
|
|
bpy.ops.object.mode_set(mode="EDIT") |
|
|
|
|
|
bpy.ops.mesh.select_all(action="SELECT") |
|
|
|
|
|
bpy.ops.mesh.sort_elements(type='VIEW_ZAXIS', elements={'FACE'}, reverse=False) |
|
|
|
|
|
bm = bmesh.from_edit_mesh(bpy.context.active_object.data) |
|
|
|
|
|
polygons = [] |
|
|
|
|
|
edges = [] |
|
|
|
|
|
|
|
|
|
|
|
self.select_border(bpy.context) |
|
|
|
|
|
bm.faces.ensure_lookup_table() |
|
|
|
|
|
bm.verts.ensure_lookup_table() |
|
|
|
|
|
bm.edges.ensure_lookup_table() |
|
|
|
|
|
for face in bm.faces: |
|
|
|
|
|
if not face.select: |
|
|
|
|
|
continue |
|
|
|
|
|
verts = [] |
|
|
|
|
|
for vert in face.verts: |
|
|
|
|
|
co = bpy_extras.object_utils.world_to_camera_view(self.scene, self.c, vert.co) |
|
|
|
|
|
verts.append([co[0], co[1]]) |
|
|
|
|
|
verts.append(verts[0]) |
|
|
|
|
|
polygons.append({"verts": verts, "type": "bright" if face.material_index == 1 else "dark"}) |
|
|
|
|
|
for edge in face.edges: |
|
|
|
|
|
if not edge.select: |
|
|
|
|
|
continue |
|
|
|
|
|
co1 = bpy_extras.object_utils.world_to_camera_view(self.scene, self.c, edge.verts[0].co) |
|
|
|
|
|
co2 = bpy_extras.object_utils.world_to_camera_view(self.scene, self.c, edge.verts[1].co) |
|
|
|
|
|
polygons.append({"type": "edge", "verts": [ |
|
|
|
|
|
[co1[0], co1[1]], |
|
|
|
|
|
[co2[0], co2[1]] |
|
|
|
|
|
]}) |
|
|
|
|
|
bm.free() |
|
|
|
|
|
bpy.ops.object.mode_set(mode="OBJECT") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with open(f"/tmp/polygons-{angles[3]}.json", "w", encoding="utf-8") as file: |
|
|
|
|
|
json.dump({"polygons": polygons}, file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def export_data(self): |
|
|
|
|
|
with open(f"/tmp/data-{self.b.name}.json", "w", encoding="utf-8") as file: |
|
|
|
|
|
json.dump({"name": self.b.name, "views": self.data}, file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def register(): |
|
|
|
|
|
bpy.utils.register_class(ModalTimerOperator) |
|
|
|
|
|
bpy.types.VIEW3D_MT_object.append(ModalTimerOperator.menu_func) |
|
|
|
|
|
|
|
|
|
|
|
def unregister(): |
|
|
|
|
|
bpy.utils.unregister_class(ModalTimerOperator) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
register() |
|
|
|