Alembic export: write curve/NURBS as mesh
[blender.git] / source / blender / editors / io / io_cache.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2016 Blender Foundation.
19  * All rights reserved.
20  *
21  * ***** END GPL LICENSE BLOCK *****
22  *
23  */
24
25 /** \file blender/editors/io/io_cache.c
26  *  \ingroup editor/io
27  */
28
29 #include "MEM_guardedalloc.h"
30
31 #include "DNA_cachefile_types.h"
32 #include "DNA_space_types.h"
33
34 #include "BLI_listbase.h"
35 #include "BLI_path_util.h"
36 #include "BLI_string.h"
37
38 #include "BKE_cachefile.h"
39 #include "BKE_context.h"
40 #include "BKE_library.h"
41 #include "BKE_main.h"
42 #include "BKE_report.h"
43
44 #include "RNA_access.h"
45
46 #include "UI_interface.h"
47
48 #include "WM_api.h"
49 #include "WM_types.h"
50
51 #include "io_cache.h"
52
53 static void cachefile_init(bContext *C, wmOperator *op)
54 {
55         PropertyPointerRNA *pprop;
56
57         op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
58         UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
59 }
60
61 static int cachefile_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
62 {
63         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
64                 char filepath[FILE_MAX];
65                 Main *bmain = CTX_data_main(C);
66
67                 BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
68                 BLI_path_extension_replace(filepath, sizeof(filepath), ".abc");
69                 RNA_string_set(op->ptr, "filepath", filepath);
70         }
71
72         cachefile_init(C, op);
73
74         WM_event_add_fileselect(C, op);
75
76         return OPERATOR_RUNNING_MODAL;
77
78         UNUSED_VARS(event);
79 }
80
81 static void open_cancel(bContext *UNUSED(C), wmOperator *op)
82 {
83         MEM_freeN(op->customdata);
84         op->customdata = NULL;
85 }
86
87 static int cachefile_open_exec(bContext *C, wmOperator *op)
88 {
89         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
90                 BKE_report(op->reports, RPT_ERROR, "No filename given");
91                 return OPERATOR_CANCELLED;
92         }
93
94         char filename[FILE_MAX];
95         RNA_string_get(op->ptr, "filepath", filename);
96
97         Main *bmain = CTX_data_main(C);
98
99         CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename), 0);
100         BLI_strncpy(cache_file->filepath, filename, FILE_MAX);
101         BKE_cachefile_reload(bmain, cache_file);
102
103         /* Will be set when running invoke, not exec directly. */
104         if (op->customdata != NULL) {
105                 /* hook into UI */
106                 PropertyPointerRNA *pprop = op->customdata;
107                 if (pprop->prop) {
108                         /* when creating new ID blocks, use is already 1, but RNA
109                          * pointer se also increases user, so this compensates it */
110                         id_us_min(&cache_file->id);
111
112                         PointerRNA idptr;
113                         RNA_id_pointer_create(&cache_file->id, &idptr);
114                         RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
115                         RNA_property_update(C, &pprop->ptr, pprop->prop);
116                 }
117
118                 MEM_freeN(op->customdata);
119         }
120
121         return OPERATOR_FINISHED;
122 }
123
124 void CACHEFILE_OT_open(wmOperatorType *ot)
125 {
126         ot->name = "Open Cache File";
127         ot->description = "Load a cache file";
128         ot->idname = "CACHEFILE_OT_open";
129
130         ot->invoke = cachefile_open_invoke;
131         ot->exec = cachefile_open_exec;
132         ot->cancel = open_cancel;
133
134         WM_operator_properties_filesel(ot, FILE_TYPE_ALEMBIC | FILE_TYPE_FOLDER,
135                                        FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH,
136                                        FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
137 }
138
139 /* ***************************** Reload Operator **************************** */
140
141 static int cachefile_reload_exec(bContext *C, wmOperator *op)
142 {
143         CacheFile *cache_file = CTX_data_edit_cachefile(C);
144
145         if (!cache_file) {
146                 return OPERATOR_CANCELLED;
147         }
148
149         Main *bmain = CTX_data_main(C);
150
151         BLI_freelistN(&cache_file->object_paths);
152         BKE_cachefile_reload(bmain, cache_file);
153
154         return OPERATOR_FINISHED;
155
156         UNUSED_VARS(op);
157 }
158
159 void CACHEFILE_OT_reload(wmOperatorType *ot)
160 {
161         ot->name = "Refresh Archive";
162         ot->description = "Update objects paths list with new data from the archive";
163         ot->idname = "CACHEFILE_OT_reload";
164
165         /* api callbacks */
166         ot->exec = cachefile_reload_exec;
167
168         /* flags */
169         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
170 }