addons-contrib: objects.link/unlink syntax update
[blender-addons-contrib.git] / curve_tools / auto_loft.py
1 import bpy
2 from bpy.props import BoolProperty
3 from bpy.types import Operator, Panel
4 from curve_tools.Surfaces import LoftedSurface
5 from curve_tools.Curves import Curve
6 from curve_tools import Util
7
8
9 class OperatorAutoLoftCurves(Operator):
10     bl_idname = "curvetools2.create_auto_loft"
11     bl_label = "Loft"
12     bl_description = "Lofts selected curves"
13
14
15     @classmethod
16     def poll(cls, context):
17         return Util.Selected2Curves()
18
19
20     def execute(self, context):
21         #print("### TODO: OperatorLoftCurves.execute()")
22         mesh = bpy.data.meshes.new("LoftMesh")
23
24         curve0 = context.selected_objects[0]
25         curve1 = context.selected_objects[1]
26
27         ls = LoftedSurface(Curve(curve0), Curve(curve1), "AutoLoft")
28
29         ls.bMesh.to_mesh(mesh)
30
31         loftobj = bpy.data.objects.new(self.name, mesh)
32
33         context.collection.objects.link(loftobj)
34         loftobj["autoloft"] = True
35         if loftobj.get('_RNA_UI') is None:
36             loftobj['_RNA_UI'] = {}
37         loftobj['_RNA_UI']["autoloft"] = {
38                            "name": "Auto Loft",
39                            "description": "Auto loft from %s to %s" % (curve0.name, curve1.name),
40                            "curve0": curve0.name,
41                            "curve1": curve1.name}
42         print(loftobj['_RNA_UI'].to_dict())
43         self.report({'INFO'}, "OperatorAutoLoftCurves.execute()")
44
45         return {'FINISHED'}
46
47
48 class AutoLoftModalOperator(Operator):
49     """Auto Loft"""
50     bl_idname = "wm.auto_loft_curve"
51     bl_label = "Auto Loft"
52     bl_description = "Lofts selected curves"
53
54     _timer = None
55     @classmethod
56     def poll(cls, context):
57         # two curves selected.
58         return True
59
60     def modal(self, context, event):
61         scene = context.scene
62         wm = context.window_manager
63         if event.type in {'ESC'}:
64             wm.auto_loft = False
65
66         if not wm.auto_loft:
67             self.cancel(context)
68             return {'CANCELLED'}
69
70         if event.type == 'TIMER':
71             lofters = [o for o in scene.objects if "autoloft" in o.keys()]
72             # quick hack
73             #print("TIMER", lofters)
74
75             for loftmesh in lofters:
76                 loftmesh.hide_select = True
77                 rna = loftmesh['_RNA_UI']["autoloft"].to_dict()
78                 curve0 = scene.objects.get(rna["curve0"])
79                 curve1 = scene.objects.get(rna["curve1"])
80                 if curve0 and curve1:
81                     ls = LoftedSurface(Curve(curve0), Curve(curve1), loftmesh.name)
82                     ls.bMesh.to_mesh(loftmesh.data)
83
84         return {'PASS_THROUGH'}
85
86     def execute(self, context):
87         wm = context.window_manager
88         self._timer = wm.event_timer_add(0.1, context.window)
89         wm.modal_handler_add(self)
90         return {'RUNNING_MODAL'}
91
92     def cancel(self, context):
93         wm = context.window_manager
94         wm.event_timer_remove(self._timer)
95
96
97
98 def run_auto_loft(self, context):
99     if self.auto_loft:
100         bpy.ops.wm.auto_loft_curve()
101     return None
102
103 def register():
104     bpy.utils.register_class(AutoLoftModalOperator)
105     bpy.utils.register_class(OperatorAutoLoftCurves)
106     bpy.types.WindowManager.auto_loft = BoolProperty(default=False,
107                                                      name="Auto Loft",
108                                                      update=run_auto_loft)
109     bpy.context.window_manager.auto_loft = False
110
111 def unregister():
112     bpy.utils.unregister_class(AutoLoftModalOperator)
113     bpy.utils.unregister_class(OperatorAutoLoftCurves)
114
115 if __name__ == "__main__":
116     register()
117
118
119     # test call
120     #bpy.ops.wm.modal_timer_operator()