Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
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) 2010 Blender Foundation. | |
19 * All rights reserved. | |
20 * | |
21 * The Original Code is: all of this file. | |
22 * | |
23 * Contributor(s): none yet. | |
24 * | |
25 * ***** END GPL LICENSE BLOCK ***** | |
26 */ | |
27 | |
28 /** \file blender/freestyle/intern/blender_interface/FRS_freestyle.cpp | |
29 * \ingroup freestyle | |
30 */ | |
31 | |
32 #include <iostream> | |
33 #include <map> | |
34 #include <set> | |
35 | |
36 #include "../application/AppCanvas.h" | |
37 #include "../application/AppConfig.h" | |
38 #include "../application/AppView.h" | |
39 #include "../application/Controller.h" | |
40 | |
41 #include "BKE_global.h" | |
42 | |
43 using namespace std; | |
44 | |
45 // XXX Are those "ifdef __cplusplus" useful here? | |
46 #ifdef __cplusplus | |
47 extern "C" { | |
48 #endif | |
49 | |
50 #include "MEM_guardedalloc.h" | |
51 | |
52 #include "DNA_camera_types.h" | |
53 #include "DNA_freestyle_types.h" | |
54 #include "DNA_group_types.h" | |
55 #include "DNA_text_types.h" | |
56 | |
57 #include "BKE_global.h" | |
58 #include "BKE_library.h" | |
59 #include "BKE_linestyle.h" | |
60 #include "BKE_main.h" | |
61 #include "BKE_text.h" | |
62 | |
63 #include "BLI_blenlib.h" | |
64 #include "BLI_math.h" | |
65 | |
66 #include "BPY_extern.h" | |
67 | |
68 #include "renderpipeline.h" | |
69 #include "pixelblending.h" | |
70 | |
71 #include "FRS_freestyle.h" | |
72 #include "FRS_freestyle_config.h" | |
73 | |
74 #define DEFAULT_SPHERE_RADIUS 1.0f | |
75 #define DEFAULT_DKR_EPSILON 0.0f | |
76 | |
77 // Freestyle configuration | |
78 static short freestyle_is_initialized = 0; | |
79 static Config::Path *pathconfig = NULL; | |
80 static Controller *controller = NULL; | |
81 static AppView *view = NULL; | |
82 | |
83 // line set buffer for copy & paste | |
84 static FreestyleLineSet lineset_buffer; | |
85 static bool lineset_copied = false; | |
86 | |
87 // camera information | |
88 float freestyle_viewpoint[3]; | |
89 float freestyle_mv[4][4]; | |
90 float freestyle_proj[4][4]; | |
91 int freestyle_viewport[4]; | |
92 | |
93 // current scene | |
94 Scene *freestyle_scene; | |
95 | |
96 string default_module_path; | |
97 | |
98 // function declarations | |
99 static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *linese t); | |
100 static void copy_module(FreestyleModuleConfig *new_module, FreestyleModuleConfig *module); | |
101 | |
102 //======================================================= | |
103 // Initialization· | |
104 //======================================================= | |
105 | |
106 void FRS_initialize() | |
107 { | |
108 if (freestyle_is_initialized) | |
109 return; | |
110 | |
111 pathconfig = new Config::Path; | |
112 controller = new Controller(); | |
113 view = new AppView; | |
114 controller->setView(view); | |
115 controller->Clear(); | |
116 freestyle_scene = NULL; | |
117 lineset_copied = false; | |
118 | |
119 default_module_path = pathconfig->getProjectDir() + Config::DIR_SEP + "s tyle_modules" + | |
120 Config::DIR_SEP + "contour.py"; | |
121 | |
122 freestyle_is_initialized = 1; | |
123 } | |
124 | |
125 void FRS_set_context(bContext *C) | |
126 { | |
127 if (G.debug & G_DEBUG_FREESTYLE) { | |
128 cout << "FRS_set_context: context 0x" << C << " scene 0x" << CTX _data_scene(C) << endl; | |
129 } | |
130 controller->setContext(C); | |
131 } | |
132 | |
133 void FRS_read_file(bContext *C) | |
134 { | |
135 lineset_copied = false; | |
136 } | |
137 | |
138 void FRS_exit() | |
139 { | |
140 delete pathconfig; | |
141 delete controller; | |
142 delete view; | |
143 } | |
144 | |
145 //======================================================= | |
146 // Rendering· | |
147 //======================================================= | |
148 | |
149 static void init_view(Render *re) | |
150 { | |
151 int width = re->winx; | |
152 int height = re->winy; | |
153 int xmin = re->disprect.xmin; | |
154 int ymin = re->disprect.ymin; | |
155 int xmax = re->disprect.xmax; | |
156 int ymax = re->disprect.ymax; | |
157 | |
158 float thickness = 1.0f; | |
159 switch (re->r.line_thickness_mode) { | |
160 case R_LINE_THICKNESS_ABSOLUTE: | |
161 thickness = re->r.unit_line_thickness * (re->r.size / 100.f); | |
162 break; | |
163 case R_LINE_THICKNESS_RELATIVE: | |
164 thickness = height / 480.f; | |
165 break; | |
166 } | |
167 | |
168 freestyle_viewport[0] = freestyle_viewport[1] = 0; | |
169 freestyle_viewport[2] = width; | |
170 freestyle_viewport[3] = height; | |
171 | |
172 view->setWidth(width); | |
173 view->setHeight(height); | |
174 view->setBorder(xmin, ymin, xmax, ymax); | |
175 view->setThickness(thickness); | |
176 | |
177 if (G.debug & G_DEBUG_FREESTYLE) { | |
178 cout << "\n=== Dimensions of the 2D image coordinate system == =" << endl; | |
179 cout << "Width : " << width << endl; | |
180 cout << "Height : " << height << endl; | |
181 if (re->r.mode & R_BORDER) | |
182 cout << "Border : (" << xmin << ", " << ymin << ") - (" << xmax << ", " << ymax << ")" << endl; | |
183 cout << "Unit line thickness : " << thickness << " pixel(s)" << endl; | |
184 } | |
185 } | |
186 | |
187 static void init_camera(Render *re) | |
188 { | |
189 // It is assumed that imported meshes are in the camera coordinate syste m. | |
190 // Therefore, the view point (i.e., camera position) is at the origin, a nd | |
191 // the the model-view matrix is simply the identity matrix. | |
192 | |
193 freestyle_viewpoint[0] = 0.0; | |
194 freestyle_viewpoint[1] = 0.0; | |
195 freestyle_viewpoint[2] = 0.0; | |
196 | |
197 for (int i = 0; i < 4; i++) { | |
ideasman42
2013/03/02 10:56:47
copy_m4m4 would do here.
kjym3
2013/03/03 01:58:03
Done. Also used unit_m4() for setting freestyle_m
| |
198 for (int j = 0; j < 4; j++) | |
199 freestyle_mv[i][j] = (i == j) ? 1.0 : 0.0; | |
200 } | |
201 | |
202 for (int i = 0; i < 4; i++) { | |
203 for (int j = 0; j < 4; j++) | |
204 freestyle_proj[i][j] = re->winmat[i][j]; | |
205 } | |
206 | |
207 #if 0 | |
208 print_m4("mv", freestyle_mv); | |
209 print_m4("proj", freestyle_proj); | |
210 #endif | |
211 } | |
212 | |
213 static char *escape_quotes(char *name) | |
214 { | |
215 char *s = (char*)MEM_mallocN(strlen(name) * 2 + 1, "escape_quotes"); | |
216 char *p = s; | |
217 while (*name) { | |
218 if (*name == '\'') | |
219 *(p++) = '\\'; | |
220 *(p++) = *(name++); | |
221 } | |
222 *p = '\0'; | |
223 return s; | |
224 } | |
225 | |
226 static Text *create_lineset_handler(char *layer_name, char *lineset_name) | |
227 { | |
228 char *s1 = escape_quotes(layer_name); | |
229 char *s2 = escape_quotes(lineset_name); | |
230 Text *text = BKE_text_add(G.main, lineset_name); | |
231 BKE_text_write(text, "import parameter_editor; parameter_editor.process( '"); | |
232 BKE_text_write(text, s1); | |
233 BKE_text_write(text, "', '"); | |
234 BKE_text_write(text, s2); | |
235 BKE_text_write(text, "')\n"); | |
236 MEM_freeN(s1); | |
237 MEM_freeN(s2); | |
238 return text; | |
239 } | |
240 | |
241 struct edge_type_condition | |
242 { | |
243 int edge_type, value; | |
244 }; | |
245 | |
246 // examines the conditions and returns true if the target edge type needs to be computed | |
247 static bool test_edge_type_conditions(struct edge_type_condition *conditions, | |
248 int num_edge_types, bool logical_and, int target, bool distinct) | |
249 { | |
250 int target_condition = 0; | |
251 int num_non_target_positive_conditions = 0; | |
252 int num_non_target_negative_conditions = 0; | |
253 | |
254 for (int i = 0; i < num_edge_types; i++) { | |
255 if (conditions[i].edge_type == target) | |
256 target_condition = conditions[i].value; | |
257 else if (conditions[i].value > 0) | |
258 ++num_non_target_positive_conditions; | |
259 else if (conditions[i].value < 0) | |
260 ++num_non_target_negative_conditions; | |
261 } | |
262 if (distinct) { | |
263 // In this case, the 'target' edge type is assumed to appear on distinct edge | |
264 // of its own and never together with other edge types. | |
265 if (logical_and) { | |
266 if (num_non_target_positive_conditions > 0) | |
267 return false; | |
268 if (target_condition > 0) | |
269 return true; | |
270 if (target_condition < 0) | |
271 return false; | |
272 if (num_non_target_negative_conditions > 0) | |
273 return true; | |
274 } | |
275 else { | |
276 if (target_condition > 0) | |
277 return true; | |
278 if (num_non_target_negative_conditions > 0) | |
279 return true; | |
280 if (target_condition < 0) | |
281 return false; | |
282 if (num_non_target_positive_conditions > 0) | |
283 return false; | |
284 } | |
285 } | |
286 else { | |
287 // In this case, the 'target' edge type may appear together with other edge types. | |
288 if (target_condition > 0) | |
289 return true; | |
290 if (target_condition < 0) | |
291 return true; | |
292 if (logical_and) { | |
293 if (num_non_target_positive_conditions > 0) | |
294 return false; | |
295 if (num_non_target_negative_conditions > 0) | |
296 return true; | |
297 } | |
298 else { | |
299 if (num_non_target_negative_conditions > 0) | |
300 return true; | |
301 if (num_non_target_positive_conditions > 0) | |
302 return false; | |
303 } | |
304 } | |
305 return true; | |
306 } | |
307 | |
308 static void prepare(Render *re, SceneRenderLayer *srl) | |
309 { | |
310 // load mesh | |
311 re->i.infostr = "Freestyle: Mesh loading"; | |
312 re->stats_draw(re->sdh, &re->i); | |
313 re->i.infostr = NULL; | |
314 if (controller->LoadMesh(re, srl)) // returns if scene cannot be loaded or if empty | |
315 return; | |
316 if (re->test_break(re->tbh)) | |
317 return; | |
318 | |
319 // add style modules | |
320 FreestyleConfig *config = &srl->freestyleConfig; | |
321 | |
322 if (G.debug & G_DEBUG_FREESTYLE) { | |
323 cout << "\n=== Rendering options ===" << endl; | |
324 } | |
325 int layer_count = 0; | |
326 | |
327 switch (config->mode) { | |
328 case FREESTYLE_CONTROL_SCRIPT_MODE: | |
329 if (G.debug & G_DEBUG_FREESTYLE) { | |
330 cout << "Modules :" << endl; | |
331 } | |
332 for (FreestyleModuleConfig *module_conf = (FreestyleModuleConfig *)config->modules.first; | |
333 module_conf; | |
334 module_conf = module_conf->next) | |
335 { | |
336 if(module_conf->is_displayed) { | |
337 if (G.debug & G_DEBUG_FREESTYLE) { | |
338 cout << " " << layer_count+1 << ": " << module_conf->module_path << endl; | |
339 } | |
340 controller->InsertStyleModule(layer_count, modul e_conf->module_path); | |
341 controller->toggleLayer(layer_count, true); | |
342 layer_count++; | |
343 } | |
344 } | |
345 if (G.debug & G_DEBUG_FREESTYLE) { | |
346 cout << endl; | |
347 } | |
348 controller->setComputeRidgesAndValleysFlag((config->flags & FREE STYLE_RIDGES_AND_VALLEYS_FLAG) ? true : false); | |
349 controller->setComputeSuggestiveContoursFlag((config->flags & FR EESTYLE_SUGGESTIVE_CONTOURS_FLAG) ? true : false); | |
350 controller->setComputeMaterialBoundariesFlag((config->flags & FR EESTYLE_MATERIAL_BOUNDARIES_FLAG) ? true : false); | |
351 break; | |
352 case FREESTYLE_CONTROL_EDITOR_MODE: | |
353 int use_ridges_and_valleys = 0; | |
354 int use_suggestive_contours = 0; | |
355 int use_material_boundaries = 0; | |
356 struct edge_type_condition conditions[] = { | |
357 {FREESTYLE_FE_SILHOUETTE, 0}, | |
358 {FREESTYLE_FE_BORDER, 0}, | |
359 {FREESTYLE_FE_CREASE, 0}, | |
360 {FREESTYLE_FE_RIDGE_VALLEY, 0}, | |
361 {FREESTYLE_FE_SUGGESTIVE_CONTOUR, 0}, | |
362 {FREESTYLE_FE_MATERIAL_BOUNDARY, 0}, | |
363 {FREESTYLE_FE_CONTOUR, 0}, | |
364 {FREESTYLE_FE_EXTERNAL_CONTOUR, 0}, | |
365 {FREESTYLE_FE_EDGE_MARK, 0} | |
366 }; | |
367 int num_edge_types = sizeof(conditions) / sizeof(struct edge_typ e_condition); | |
368 if (G.debug & G_DEBUG_FREESTYLE) { | |
369 cout << "Linesets:" << endl; | |
370 } | |
371 for (FreestyleLineSet *lineset = (FreestyleLineSet*)config->line sets.first; | |
372 lineset; | |
373 lineset = lineset->next) | |
374 { | |
375 if (lineset->flags & FREESTYLE_LINESET_ENABLED) { | |
376 if (G.debug & G_DEBUG_FREESTYLE) { | |
377 cout << " " << layer_count+1 << ": " << lineset->name << " - " | |
378 << lineset->linestyle->id.name+2 << endl; | |
379 } | |
380 Text *text = create_lineset_handler(srl->name, l ineset->name); | |
381 controller->InsertStyleModule(layer_count, lines et->name, text); | |
382 controller->toggleLayer(layer_count, true); | |
383 if (!(lineset->selection & FREESTYLE_SEL_EDGE_TY PES) || !lineset->edge_types) { | |
384 ++use_ridges_and_valleys; | |
385 ++use_suggestive_contours; | |
386 ++use_material_boundaries; | |
387 } | |
388 else { | |
389 // conditions for feature edge selection by edge types | |
390 for (int i = 0; i < num_edge_types; i++) { | |
391 if (!(lineset->edge_types & cond itions[i].edge_type)) | |
392 conditions[i].value = 0; // no condition specified | |
393 else if (!(lineset->exclude_edge _types & conditions[i].edge_type)) | |
394 conditions[i].value = 1; // condition: X | |
395 else | |
396 conditions[i].value = -1 ; // condition: NOT X | |
397 } | |
398 // logical operator for the selection co nditions | |
399 bool logical_and = ((lineset->flags & FR EESTYLE_LINESET_FE_AND) != 0); | |
400 // negation operator | |
401 if (lineset->flags & FREESTYLE_LINESET_F E_NOT) { | |
402 // convert an Exclusive conditio n into an Inclusive equivalent using De Morgan's laws: | |
403 // NOT (X OR Y) --> (NOT X) AN D (NOT Y) | |
404 // NOT (X AND Y) --> (NOT X) O R (NOT Y) | |
405 for (int i = 0; i < num_edge_typ es; i++) | |
406 conditions[i].value *= - 1; | |
407 logical_and = !logical_and; | |
408 } | |
409 if (test_edge_type_conditions(conditions , num_edge_types, logical_and, | |
410 FREESTYLE_ FE_RIDGE_VALLEY, true)) | |
411 { | |
412 ++use_ridges_and_valleys; | |
413 } | |
414 if (test_edge_type_conditions(conditions , num_edge_types, logical_and, | |
415 FREESTYLE_ FE_SUGGESTIVE_CONTOUR, true)) | |
416 { | |
417 ++use_suggestive_contours; | |
418 } | |
419 if (test_edge_type_conditions(conditions , num_edge_types, logical_and, | |
420 FREESTYLE_ FE_MATERIAL_BOUNDARY, true)) | |
421 { | |
422 ++use_material_boundaries; | |
423 } | |
424 } | |
425 layer_count++; | |
426 } | |
427 } | |
428 controller->setComputeRidgesAndValleysFlag(use_ridges_and_valley s > 0); | |
429 controller->setComputeSuggestiveContoursFlag(use_suggestive_cont ours > 0); | |
430 controller->setComputeMaterialBoundariesFlag(use_material_bounda ries > 0); | |
431 break; | |
432 } | |
433 | |
434 // set parameters | |
435 if (config->flags & FREESTYLE_ADVANCED_OPTIONS_FLAG) { | |
436 controller->setSphereRadius(config->sphere_radius); | |
437 controller->setSuggestiveContourKrDerivativeEpsilon(config->dkr_ epsilon); | |
438 } | |
439 else { | |
440 controller->setSphereRadius(DEFAULT_SPHERE_RADIUS); | |
441 controller->setSuggestiveContourKrDerivativeEpsilon(DEFAULT_DKR_ EPSILON); | |
442 } | |
443 controller->setFaceSmoothness((config->flags & FREESTYLE_FACE_SMOOTHNESS _FLAG) ? true : false); | |
444 controller->setCreaseAngle(RAD2DEGF(config->crease_angle)); | |
445 controller->setVisibilityAlgo((config->flags & FREESTYLE_CULLING) ? | |
446 FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE : | |
447 FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE); | |
448 | |
449 if (G.debug & G_DEBUG_FREESTYLE) { | |
450 cout << "Crease angle : " << controller->getCreaseAngle() << end l; | |
451 cout << "Sphere radius : " << controller->getSphereRadius() << e ndl; | |
452 cout << "Face smoothness : " << (controller->getFaceSmoothness() ? "enabled" : "disabled") << endl; | |
453 cout << "Redges and valleys : " << (controller->getComputeRidges AndValleysFlag() ? "enabled" : "disabled") | |
454 << endl; | |
455 cout << "Suggestive contours : " << (controller->getComputeSugge stiveContoursFlag() ? "enabled" : "disabled") | |
456 << endl; | |
457 cout << "Suggestive contour Kr derivative epsilon : " << control ler->getSuggestiveContourKrDerivativeEpsilon() | |
458 << endl; | |
459 cout << "Material boundaries : " << (controller->getComputeMater ialBoundariesFlag() ? "enabled" : "disabled") | |
460 << endl; | |
461 cout << endl; | |
462 } | |
463 | |
464 // set diffuse and z depth passes | |
465 RenderLayer *rl = RE_GetRenderLayer(re->result, srl->name); | |
466 bool diffuse = false, z = false; | |
467 for (RenderPass *rpass = (RenderPass*)rl->passes.first; rpass; rpass = r pass->next) { | |
468 switch (rpass->passtype) { | |
469 case SCE_PASS_DIFFUSE: | |
470 controller->setPassDiffuse(rpass->rect, rpass->rectx, rp ass->recty); | |
471 diffuse = true; | |
472 break; | |
473 case SCE_PASS_Z: | |
474 controller->setPassZ(rpass->rect, rpass->rectx, rpass->r ecty); | |
475 z = true; | |
476 break; | |
477 } | |
478 } | |
479 if (G.debug & G_DEBUG_FREESTYLE) { | |
480 cout << "Passes :" << endl; | |
481 cout << " Diffuse = " << (diffuse ? "enabled" : "disabled") << endl; | |
482 cout << " Z = " << (z ? "enabled" : "disabled") << endl; | |
483 } | |
484 | |
485 // compute view map | |
486 re->i.infostr = "Freestyle: View map creation"; | |
487 re->stats_draw(re->sdh, &re->i); | |
488 re->i.infostr = NULL; | |
489 controller->ComputeViewMap(); | |
490 } | |
491 | |
492 void FRS_composite_result(Render* re, SceneRenderLayer* srl, Render* freestyle_r ender) | |
493 { | |
494 RenderLayer *rl; | |
495 float *src, *dest, *pixSrc, *pixDest; | |
496 int x, y, rectx, recty; | |
497 | |
498 if (freestyle_render == NULL || freestyle_render->result == NULL) | |
499 return; | |
500 | |
501 rl = render_get_active_layer( freestyle_render, freestyle_render->result ); | |
502 if (!rl || rl->rectf == NULL) { | |
503 if (G.debug & G_DEBUG_FREESTYLE) { | |
504 cout << "Cannot find Freestyle result image" << endl; | |
505 } | |
506 return; | |
507 } | |
508 src = rl->rectf; | |
509 #if 0 | |
510 if (G.debug & G_DEBUG_FREESTYLE) { | |
511 cout << "src: " << rl->rectx << " x " << rl->recty << endl; | |
512 } | |
513 #endif | |
514 | |
515 rl = RE_GetRenderLayer(re->result, srl->name); | |
516 if (!rl || rl->rectf == NULL) { | |
517 if (G.debug & G_DEBUG_FREESTYLE) { | |
518 cout << "No layer to composite to" << endl; | |
519 } | |
520 return; | |
521 } | |
522 dest = rl->rectf; | |
523 #if 0 | |
524 if (G.debug & G_DEBUG_FREESTYLE) { | |
525 cout << "dest: " << rl->rectx << " x " << rl->recty << endl; | |
526 } | |
527 #endif | |
528 | |
529 rectx = re->rectx; | |
530 recty = re->recty; | |
531 for (y = 0; y < recty; y++) { | |
532 for (x = 0; x < rectx; x++) { | |
533 pixSrc = src + 4 * (rectx * y + x); | |
534 if (pixSrc[3] > 0.0) { | |
535 pixDest = dest + 4 * (rectx * y + x); | |
536 addAlphaOverFloat(pixDest, pixSrc); | |
537 } | |
538 } | |
539 } | |
540 } | |
541 | |
542 static int displayed_layer_count(SceneRenderLayer *srl) | |
543 { | |
544 int count = 0; | |
545 | |
546 switch (srl->freestyleConfig.mode) { | |
547 case FREESTYLE_CONTROL_SCRIPT_MODE: | |
548 for (FreestyleModuleConfig *module = (FreestyleModuleConfig*)srl ->freestyleConfig.modules.first; | |
549 module; | |
550 module = module->next) | |
551 { | |
552 if (module->is_displayed) | |
553 count++; | |
554 } | |
555 break; | |
556 case FREESTYLE_CONTROL_EDITOR_MODE: | |
557 for (FreestyleLineSet *lineset = (FreestyleLineSet*)srl->freesty leConfig.linesets.first; | |
558 lineset; | |
559 lineset = lineset->next) | |
560 { | |
561 if (lineset->flags & FREESTYLE_LINESET_ENABLED) | |
562 count++; | |
563 } | |
564 break; | |
565 } | |
566 return count; | |
567 } | |
568 | |
569 int FRS_is_freestyle_enabled(SceneRenderLayer *srl) | |
570 { | |
571 return (!(srl->layflag & SCE_LAY_DISABLE) && srl->layflag & SCE_LAY_FRS && displayed_layer_count(srl) > 0); | |
572 } | |
573 | |
574 void FRS_init_stroke_rendering(Render *re) | |
575 { | |
576 if (G.debug & G_DEBUG_FREESTYLE) { | |
577 cout << endl; | |
578 cout << "#====================================================== =========" << endl; | |
579 cout << "# Freestyle" << endl; | |
580 cout << "#====================================================== =========" << endl; | |
581 } | |
582 | |
583 init_view(re); | |
584 init_camera(re); | |
585 | |
586 controller->ResetRenderCount(); | |
587 } | |
588 | |
589 Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl) | |
590 { | |
591 Render *freestyle_render = NULL; | |
592 | |
593 RenderMonitor monitor(re); | |
594 controller->setRenderMonitor(&monitor); | |
595 | |
596 if (G.debug & G_DEBUG_FREESTYLE) { | |
597 cout << endl; | |
598 cout << "------------------------------------------------------- ---" << endl; | |
599 cout << "| " << (re->scene->id.name + 2) << "|" << srl->name << endl; | |
600 cout << "------------------------------------------------------- ---" << endl; | |
601 } | |
602 | |
603 // prepare Freestyle: | |
604 // - load mesh | |
605 // - add style modules | |
606 // - set parameters | |
607 // - compute view map | |
608 prepare(re, srl); | |
609 | |
610 if (re->test_break(re->tbh)) { | |
611 controller->CloseFile(); | |
612 if (G.debug & G_DEBUG_FREESTYLE) { | |
613 cout << "Break" << endl; | |
614 } | |
615 return NULL; | |
616 } | |
617 | |
618 // render and composite Freestyle result | |
619 if (controller->_ViewMap) { | |
620 // render strokes | |
621 re->i.infostr = "Freestyle: Stroke rendering"; | |
622 re->stats_draw(re->sdh, &re->i); | |
623 re->i.infostr = NULL; | |
624 freestyle_scene = re->scene; | |
625 controller->DrawStrokes(); | |
626 freestyle_render = controller->RenderStrokes(re); | |
627 controller->CloseFile(); | |
628 freestyle_scene = NULL; | |
629 | |
630 // composite result | |
631 FRS_composite_result(re, srl, freestyle_render); | |
632 RE_FreeRenderResult(freestyle_render->result); | |
633 freestyle_render->result = NULL; | |
634 } | |
635 | |
636 return freestyle_render; | |
637 } | |
638 | |
639 void FRS_finish_stroke_rendering(Render *re) { | |
640 // clear canvas | |
641 controller->Clear(); | |
642 } | |
643 | |
644 //======================================================= | |
645 // Freestyle Panel Configuration | |
646 //======================================================= | |
647 | |
648 void FRS_init_freestyle_config(FreestyleConfig *config) | |
649 { | |
irieshinsuke
2013/03/21 12:39:58
Why these default values are different from the fa
kjym3
2013/03/23 22:46:08
Fixed in revision 55484. Also fixed the default v
irieshinsuke
2013/03/30 09:55:14
I think the default line color should remain black
kjym3
2013/04/03 00:25:10
Fixed in revision 55677.
| |
650 config->mode = FREESTYLE_CONTROL_SCRIPT_MODE; | |
651 | |
652 config->modules.first = config->modules.last = NULL; | |
653 config->flags = 0; | |
654 config->sphere_radius = DEFAULT_SPHERE_RADIUS; | |
655 config->dkr_epsilon = DEFAULT_DKR_EPSILON; | |
656 config->crease_angle = DEG2RADF(120.0f); | |
657 | |
658 config->linesets.first = config->linesets.last = NULL; | |
659 } | |
660 | |
661 void FRS_free_freestyle_config(FreestyleConfig *config) | |
662 { | |
663 FreestyleLineSet *lineset; | |
664 | |
665 for (lineset = (FreestyleLineSet*)config->linesets.first; lineset; lines et = lineset->next) { | |
666 if (lineset->group) { | |
667 lineset->group->id.us--; | |
668 lineset->group = NULL; | |
669 } | |
670 lineset->linestyle->id.us--; | |
671 lineset->linestyle = NULL; | |
672 } | |
673 BLI_freelistN(&config->linesets); | |
674 BLI_freelistN(&config->modules); | |
675 } | |
676 | |
677 void FRS_copy_freestyle_config(FreestyleConfig *new_config, FreestyleConfig *con fig) | |
678 { | |
679 FreestyleLineSet *lineset, *new_lineset; | |
680 FreestyleModuleConfig *module, *new_module; | |
681 | |
682 new_config->mode = config->mode; | |
683 new_config->raycasting_algorithm = config->raycasting_algorithm; /* depr ecated */ | |
684 new_config->flags = config->flags; | |
685 new_config->sphere_radius = config->sphere_radius; | |
686 new_config->dkr_epsilon = config->dkr_epsilon; | |
687 new_config->crease_angle = config->crease_angle; | |
688 | |
689 new_config->linesets.first = new_config->linesets.last = NULL; | |
690 for (lineset = (FreestyleLineSet*)config->linesets.first; lineset; lines et = lineset->next) { | |
691 new_lineset = FRS_alloc_lineset(); | |
692 copy_lineset(new_lineset, lineset); | |
693 BLI_addtail(&new_config->linesets, (void*)new_lineset); | |
694 } | |
695 | |
696 new_config->modules.first = new_config->modules.last = NULL; | |
697 for (module = (FreestyleModuleConfig*)config->modules.first; module; mod ule = module->next) { | |
698 new_module = FRS_alloc_module(); | |
699 copy_module(new_module, module); | |
700 BLI_addtail(&new_config->modules, (void*)new_module); | |
701 } | |
702 } | |
703 | |
704 static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *linese t) | |
705 { | |
706 new_lineset->linestyle = lineset->linestyle; | |
707 new_lineset->linestyle->id.us++; | |
708 new_lineset->flags = lineset->flags; | |
709 new_lineset->selection = lineset->selection; | |
710 new_lineset->qi = lineset->qi; | |
711 new_lineset->qi_start = lineset->qi_start; | |
712 new_lineset->qi_end = lineset->qi_end; | |
713 new_lineset->edge_types = lineset->edge_types; | |
714 new_lineset->exclude_edge_types = lineset->exclude_edge_types; | |
715 new_lineset->group = lineset->group; | |
716 if (new_lineset->group) { | |
717 new_lineset->group->id.us++; | |
718 } | |
719 strcpy(new_lineset->name, lineset->name); | |
720 } | |
721 | |
722 FreestyleModuleConfig *FRS_alloc_module() | |
723 { | |
724 return (FreestyleModuleConfig*)MEM_callocN(sizeof(FreestyleModuleConfig) , "style module configuration"); | |
725 } | |
726 | |
727 void FRS_add_module(FreestyleConfig *config) | |
728 { | |
729 FreestyleModuleConfig *module_conf = (FreestyleModuleConfig*)MEM_callocN (sizeof(FreestyleModuleConfig), | |
730 "style module configuration"); | |
731 BLI_addtail(&config->modules, (void*)module_conf); | |
732 | |
733 strcpy(module_conf->module_path, default_module_path.c_str()); | |
734 module_conf->is_displayed = 1; | |
735 } | |
736 | |
737 static void copy_module(FreestyleModuleConfig *new_module, FreestyleModuleConfig *module) | |
738 { | |
739 strcpy(new_module->module_path, module->module_path); | |
740 new_module->is_displayed = module->is_displayed; | |
741 } | |
742 | |
743 void FRS_delete_module(FreestyleConfig *config, FreestyleModuleConfig *module_co nf) | |
744 { | |
745 BLI_freelinkN(&config->modules, module_conf); | |
746 } | |
747 | |
748 void FRS_move_module_up(FreestyleConfig *config, FreestyleModuleConfig *module_c onf) | |
749 { | |
750 BLI_remlink(&config->modules, module_conf); | |
751 BLI_insertlinkbefore(&config->modules, module_conf->prev, module_conf); | |
752 } | |
753 | |
754 void FRS_move_module_down(FreestyleConfig *config, FreestyleModuleConfig *module _conf) | |
755 { | |
756 BLI_remlink(&config->modules, module_conf); | |
757 BLI_insertlinkafter(&config->modules, module_conf->next, module_conf); | |
758 } | |
759 | |
760 static void unique_lineset_name(FreestyleConfig *config, FreestyleLineSet *lines et) | |
761 { | |
762 BLI_uniquename(&config->linesets, lineset, "FreestyleLineSet", '.', offs etof(FreestyleLineSet, name), | |
763 sizeof(lineset->name)); | |
764 } | |
765 | |
766 FreestyleLineSet *FRS_alloc_lineset() | |
767 { | |
768 return (FreestyleLineSet*)MEM_callocN(sizeof(FreestyleLineSet), "Freesty le line set"); | |
769 } | |
770 | |
771 FreestyleLineSet *FRS_add_lineset(FreestyleConfig *config) | |
772 { | |
773 int lineset_index = BLI_countlist(&config->linesets); | |
774 | |
775 FreestyleLineSet *lineset = FRS_alloc_lineset(); | |
776 BLI_addtail(&config->linesets, (void*)lineset); | |
777 FRS_set_active_lineset_index(config, lineset_index); | |
778 | |
779 lineset->linestyle = FRS_new_linestyle("LineStyle", NULL); | |
780 lineset->flags |= FREESTYLE_LINESET_ENABLED; | |
781 lineset->selection = FREESTYLE_SEL_IMAGE_BORDER; | |
782 lineset->qi = FREESTYLE_QI_VISIBLE; | |
783 lineset->qi_start = 0; | |
784 lineset->qi_end = 100; | |
785 lineset->edge_types = FREESTYLE_FE_SILHOUETTE | FREESTYLE_FE_BORDER | FR EESTYLE_FE_CREASE; | |
786 lineset->exclude_edge_types = 0; | |
787 lineset->group = NULL; | |
788 if (lineset_index > 0) | |
789 sprintf(lineset->name, "LineSet %i", lineset_index + 1); | |
790 else | |
791 strcpy(lineset->name, "LineSet"); | |
792 unique_lineset_name(config, lineset); | |
793 | |
794 return lineset; | |
795 } | |
796 | |
797 void FRS_copy_active_lineset(FreestyleConfig *config) | |
798 { | |
799 FreestyleLineSet *lineset = FRS_get_active_lineset(config); | |
800 | |
801 if (lineset) { | |
802 lineset_buffer.linestyle = lineset->linestyle; | |
803 lineset_buffer.flags = lineset->flags; | |
804 lineset_buffer.selection = lineset->selection; | |
805 lineset_buffer.qi = lineset->qi; | |
806 lineset_buffer.qi_start = lineset->qi_start; | |
807 lineset_buffer.qi_end = lineset->qi_end; | |
808 lineset_buffer.edge_types = lineset->edge_types; | |
809 lineset_buffer.exclude_edge_types = lineset->exclude_edge_types; | |
810 lineset_buffer.group = lineset->group; | |
811 strcpy(lineset_buffer.name, lineset->name); | |
812 lineset_copied = true; | |
813 } | |
814 } | |
815 | |
816 void FRS_paste_active_lineset(FreestyleConfig *config) | |
817 { | |
818 if (!lineset_copied) | |
819 return; | |
820 | |
821 FreestyleLineSet *lineset = FRS_get_active_lineset(config); | |
822 | |
823 if (lineset) { | |
824 lineset->linestyle->id.us--; | |
825 lineset->linestyle = lineset_buffer.linestyle; | |
826 lineset->linestyle->id.us++; | |
827 lineset->flags = lineset_buffer.flags; | |
828 lineset->selection = lineset_buffer.selection; | |
829 lineset->qi = lineset_buffer.qi; | |
830 lineset->qi_start = lineset_buffer.qi_start; | |
831 lineset->qi_end = lineset_buffer.qi_end; | |
832 lineset->edge_types = lineset_buffer.edge_types; | |
833 lineset->exclude_edge_types = lineset_buffer.exclude_edge_types; | |
834 if (lineset->group) { | |
835 lineset->group->id.us--; | |
836 lineset->group = NULL; | |
837 } | |
838 if (lineset_buffer.group) { | |
839 lineset->group = lineset_buffer.group; | |
840 lineset->group->id.us++; | |
841 } | |
842 strcpy(lineset->name, lineset_buffer.name); | |
843 unique_lineset_name(config, lineset); | |
844 lineset->flags |= FREESTYLE_LINESET_CURRENT; | |
845 } | |
846 } | |
847 | |
848 void FRS_delete_active_lineset(FreestyleConfig *config) | |
849 { | |
850 FreestyleLineSet *lineset = FRS_get_active_lineset(config); | |
851 | |
852 if (lineset) { | |
853 if (lineset->group) { | |
854 lineset->group->id.us--; | |
855 lineset->group = NULL; | |
856 } | |
857 lineset->linestyle->id.us--; | |
858 lineset->linestyle = NULL; | |
859 BLI_remlink(&config->linesets, lineset); | |
860 MEM_freeN(lineset); | |
861 FRS_set_active_lineset_index(config, 0); | |
862 } | |
863 } | |
864 | |
865 void FRS_move_active_lineset_up(FreestyleConfig *config) | |
866 { | |
867 FreestyleLineSet *lineset = FRS_get_active_lineset(config); | |
868 | |
869 if (lineset) { | |
870 BLI_remlink(&config->linesets, lineset); | |
871 BLI_insertlinkbefore(&config->linesets, lineset->prev, lineset); | |
872 } | |
873 } | |
874 | |
875 void FRS_move_active_lineset_down(FreestyleConfig *config) | |
876 { | |
877 FreestyleLineSet *lineset = FRS_get_active_lineset(config); | |
878 | |
879 if (lineset) { | |
880 BLI_remlink(&config->linesets, lineset); | |
881 BLI_insertlinkafter(&config->linesets, lineset->next, lineset); | |
882 } | |
883 } | |
884 | |
885 FreestyleLineSet *FRS_get_active_lineset(FreestyleConfig *config) | |
886 { | |
887 FreestyleLineSet *lineset; | |
888 | |
889 for (lineset = (FreestyleLineSet*)config->linesets.first; lineset; lines et = lineset->next) { | |
890 if (lineset->flags & FREESTYLE_LINESET_CURRENT) | |
891 return lineset; | |
892 } | |
893 return NULL; | |
894 } | |
895 | |
896 short FRS_get_active_lineset_index(FreestyleConfig *config) | |
897 { | |
898 FreestyleLineSet *lineset; | |
899 short i; | |
900 | |
901 for (lineset = (FreestyleLineSet*)config->linesets.first, i = 0; lineset ; lineset = lineset->next, i++) { | |
902 if (lineset->flags & FREESTYLE_LINESET_CURRENT) | |
903 return i; | |
904 } | |
905 return 0; | |
906 } | |
907 | |
908 void FRS_set_active_lineset_index(FreestyleConfig *config, short index) | |
909 { | |
910 FreestyleLineSet *lineset; | |
911 short i; | |
912 | |
913 for (lineset = (FreestyleLineSet*)config->linesets.first, i = 0; lineset ; lineset = lineset->next, i++) { | |
914 if (i == index) | |
915 lineset->flags |= FREESTYLE_LINESET_CURRENT; | |
916 else | |
917 lineset->flags &= ~FREESTYLE_LINESET_CURRENT; | |
918 } | |
919 } | |
920 | |
921 void FRS_unlink_target_object(FreestyleConfig *config, Object *ob) | |
922 { | |
923 FreestyleLineSet *lineset; | |
924 | |
925 for (lineset = (FreestyleLineSet*)config->linesets.first; lineset; lines et = lineset->next) { | |
926 FRS_unlink_linestyle_target_object(lineset->linestyle, ob); | |
927 } | |
928 } | |
929 | |
930 #ifdef __cplusplus | |
931 } // extern "C" | |
932 #endif | |
OLD | NEW |