|  |  | @@ -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() |