Merged changes in the trunk up to revision 44797.
[blender.git] / source / blender / blenkernel / intern / linestyle.c
1 /* linestyle.c
2  *
3  * $Id$
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2010 Blender Foundation.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_object_types.h"
38 #include "DNA_material_types.h" /* for ramp blend */
39 #include "DNA_texture_types.h"
40
41 #include "BKE_global.h"
42 #include "BKE_library.h"
43 #include "BKE_linestyle.h"
44 #include "BKE_main.h"
45 #include "BKE_texture.h"
46 #include "BKE_colortools.h"
47 #include "BKE_animsys.h"
48
49 #include "BLI_blenlib.h"
50
51 static char *modifier_name[LS_MODIFIER_NUM] = {
52         NULL,
53         "Along Stroke",
54         "Distance from Camera",
55         "Distance from Object",
56         "Material",
57         "Sampling",
58         "Bezier Curve",
59         "Sinus Displacement",
60         "Spatial Noise",
61         "Perlin Noise 1D",
62         "Perlin Noise 2D",
63         "Backbone Stretcher",
64         "Tip Remover",
65         "Calligraphy",
66         "Polygonalization",
67         "Guiding Lines",
68         "Blueprint",
69         "2D Offset",
70         "2D Transform"};
71
72 static void default_linestyle_settings(FreestyleLineStyle *linestyle)
73 {
74         linestyle->panel = LS_PANEL_STROKES;
75         linestyle->r = linestyle->g = linestyle->b = 0.0;
76         linestyle->alpha = 1.0;
77         linestyle->thickness = 1.0;
78         linestyle->chaining = LS_CHAINING_PLAIN;
79         linestyle->rounds = 3;
80         linestyle->min_angle = 0.0f;
81         linestyle->max_angle = 0.0f;
82         linestyle->min_length = 0.0f;
83         linestyle->max_length = 10000.0f;
84         linestyle->split_length = 100;
85
86         linestyle->color_modifiers.first = linestyle->color_modifiers.last = NULL;
87         linestyle->alpha_modifiers.first = linestyle->alpha_modifiers.last = NULL;
88         linestyle->thickness_modifiers.first = linestyle->thickness_modifiers.last = NULL;
89         linestyle->geometry_modifiers.first = linestyle->geometry_modifiers.last = NULL;
90
91         FRS_add_linestyle_geometry_modifier(linestyle, LS_MODIFIER_SAMPLING);
92
93         linestyle->caps = LS_CAPS_BUTT;
94 }
95
96 FreestyleLineStyle *FRS_new_linestyle(char *name, struct Main *main)
97 {
98         FreestyleLineStyle *linestyle;
99
100         if (!main)
101                 main = G.main;
102
103         linestyle = (FreestyleLineStyle *)alloc_libblock(&main->linestyle, ID_LS, name);
104         
105         default_linestyle_settings(linestyle);
106
107         return linestyle;
108 }
109
110 void FRS_free_linestyle(FreestyleLineStyle *linestyle)
111 {
112         LineStyleModifier *m;
113
114         BKE_free_animdata(&linestyle->id);
115         while ((m = (LineStyleModifier *)linestyle->color_modifiers.first))
116                 FRS_remove_linestyle_color_modifier(linestyle, m);
117         while ((m = (LineStyleModifier *)linestyle->alpha_modifiers.first))
118                 FRS_remove_linestyle_alpha_modifier(linestyle, m);
119         while ((m = (LineStyleModifier *)linestyle->thickness_modifiers.first))
120                 FRS_remove_linestyle_thickness_modifier(linestyle, m);
121         while ((m = (LineStyleModifier *)linestyle->geometry_modifiers.first))
122                 FRS_remove_linestyle_geometry_modifier(linestyle, m);
123 }
124
125 FreestyleLineStyle *FRS_copy_linestyle(FreestyleLineStyle *linestyle)
126 {
127         FreestyleLineStyle *new_linestyle;
128         LineStyleModifier *m;
129
130         new_linestyle = FRS_new_linestyle(linestyle->id.name+2, NULL);
131         FRS_free_linestyle(new_linestyle);
132
133         new_linestyle->r = linestyle->r;
134         new_linestyle->g = linestyle->g;
135         new_linestyle->b = linestyle->b;
136         new_linestyle->alpha = linestyle->alpha;
137         new_linestyle->thickness = linestyle->thickness;
138         new_linestyle->flag = linestyle->flag;
139         new_linestyle->caps = linestyle->caps;
140         new_linestyle->chaining = linestyle->chaining;
141         new_linestyle->rounds = linestyle->rounds;
142         new_linestyle->min_angle = linestyle->min_angle;
143         new_linestyle->max_angle = linestyle->max_angle;
144         new_linestyle->min_length = linestyle->min_length;
145         new_linestyle->max_length = linestyle->max_length;
146         new_linestyle->split_length = linestyle->split_length;
147         new_linestyle->dash1 = linestyle->dash1;
148         new_linestyle->gap1 = linestyle->gap1;
149         new_linestyle->dash2 = linestyle->dash2;
150         new_linestyle->gap2 = linestyle->gap2;
151         new_linestyle->dash3 = linestyle->dash3;
152         new_linestyle->gap3 = linestyle->gap3;
153         new_linestyle->panel = linestyle->panel;
154         for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next)
155                 FRS_copy_linestyle_color_modifier(new_linestyle, m);
156         for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next)
157                 FRS_copy_linestyle_alpha_modifier(new_linestyle, m);
158         for (m = (LineStyleModifier *)linestyle->thickness_modifiers.first; m; m = m->next)
159                 FRS_copy_linestyle_thickness_modifier(new_linestyle, m);
160         for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next)
161                 FRS_copy_linestyle_geometry_modifier(new_linestyle, m);
162         return new_linestyle;
163 }
164
165 static LineStyleModifier *new_modifier(int type, size_t size)
166 {
167         LineStyleModifier *m;
168
169         m = (LineStyleModifier *)MEM_callocN(size, "line style modifier");
170         if (m) {
171                 m->type = type;
172                 strcpy(m->name, modifier_name[type]);
173                 m->influence = 1.0f;
174                 m->flags = LS_MODIFIER_ENABLED | LS_MODIFIER_EXPANDED;
175         }
176         return m;
177 }
178
179 static void add_to_modifier_list(ListBase *lb, LineStyleModifier *m)
180 {
181         BLI_addtail(lb, (void *)m);
182         BLI_uniquename(lb, m, modifier_name[m->type], '.', offsetof(LineStyleModifier, name), sizeof(m->name));
183 }
184
185 static LineStyleModifier *alloc_color_modifier(int type)
186 {
187         size_t size;
188
189         switch (type) {
190         case LS_MODIFIER_ALONG_STROKE:
191                 size = sizeof(LineStyleColorModifier_AlongStroke);
192                 break;
193         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
194                 size = sizeof(LineStyleColorModifier_DistanceFromCamera);
195                 break;
196         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
197                 size = sizeof(LineStyleColorModifier_DistanceFromObject);
198                 break;
199         case LS_MODIFIER_MATERIAL:
200                 size = sizeof(LineStyleColorModifier_Material);
201                 break;
202         default:
203                 return NULL; /* unknown modifier type */
204         }
205         return new_modifier(type, size);
206 }
207
208 LineStyleModifier *FRS_add_linestyle_color_modifier(FreestyleLineStyle *linestyle, int type)
209 {
210         LineStyleModifier *m;
211         
212         m = alloc_color_modifier(type);
213         if (!m)
214                 return NULL;
215         m->blend = MA_RAMP_BLEND;
216         switch (type) {
217         case LS_MODIFIER_ALONG_STROKE:
218                 ((LineStyleColorModifier_AlongStroke *)m)->color_ramp = add_colorband(1);
219                 break;
220         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
221                 ((LineStyleColorModifier_DistanceFromCamera *)m)->color_ramp = add_colorband(1);
222                 ((LineStyleColorModifier_DistanceFromCamera *)m)->range_min = 0.0f;
223                 ((LineStyleColorModifier_DistanceFromCamera *)m)->range_max = 10000.0f;
224                 break;
225         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
226                 ((LineStyleColorModifier_DistanceFromObject *)m)->target = NULL;
227                 ((LineStyleColorModifier_DistanceFromObject *)m)->color_ramp = add_colorband(1);
228                 ((LineStyleColorModifier_DistanceFromObject *)m)->range_min = 0.0f;
229                 ((LineStyleColorModifier_DistanceFromObject *)m)->range_max = 10000.0f;
230                 break;
231         case LS_MODIFIER_MATERIAL:
232                 ((LineStyleColorModifier_Material *)m)->color_ramp = add_colorband(1);
233                 ((LineStyleColorModifier_Material *)m)->mat_attr = LS_MODIFIER_MATERIAL_DIFF;
234                 break;
235         default:
236                 return NULL; /* unknown modifier type */
237         }
238         add_to_modifier_list(&linestyle->color_modifiers, m);
239
240         return m;
241 }
242
243 LineStyleModifier *FRS_copy_linestyle_color_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
244 {
245         LineStyleModifier *new_m;
246         
247         new_m = alloc_color_modifier(m->type);
248         if (!new_m)
249                 return NULL;
250         new_m->influence = m->influence;
251         new_m->flags = m->flags;
252         new_m->blend = m->blend;
253         switch (m->type) {
254         case LS_MODIFIER_ALONG_STROKE:
255                 {
256                         LineStyleColorModifier_AlongStroke *p = (LineStyleColorModifier_AlongStroke *)m;
257                         ((LineStyleColorModifier_AlongStroke *)new_m)->color_ramp = MEM_dupallocN(p->color_ramp);
258                 }
259                 break;
260         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
261                 {
262                         LineStyleColorModifier_DistanceFromCamera *p = (LineStyleColorModifier_DistanceFromCamera *)m;
263                         ((LineStyleColorModifier_DistanceFromCamera *)new_m)->color_ramp = MEM_dupallocN(p->color_ramp);
264                         ((LineStyleColorModifier_DistanceFromCamera *)new_m)->range_min = p->range_min;
265                         ((LineStyleColorModifier_DistanceFromCamera *)new_m)->range_max = p->range_max;
266                 }
267                 break;
268         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
269                 {
270                         LineStyleColorModifier_DistanceFromObject *p = (LineStyleColorModifier_DistanceFromObject *)m;
271                         if (p->target)
272                                 p->target->id.us++;
273                         ((LineStyleColorModifier_DistanceFromObject *)new_m)->target = p->target;
274                         ((LineStyleColorModifier_DistanceFromObject *)new_m)->color_ramp = MEM_dupallocN(p->color_ramp);
275                         ((LineStyleColorModifier_DistanceFromObject *)new_m)->range_min = p->range_min;
276                         ((LineStyleColorModifier_DistanceFromObject *)new_m)->range_max = p->range_max;
277                 }
278                 break;
279         case LS_MODIFIER_MATERIAL:
280                 {
281                         LineStyleColorModifier_Material *p = (LineStyleColorModifier_Material *)m;
282                         ((LineStyleColorModifier_Material *)new_m)->color_ramp = MEM_dupallocN(p->color_ramp);
283                         ((LineStyleColorModifier_Material *)new_m)->mat_attr = p->mat_attr;
284                 }
285                 break;
286         default:
287                 return NULL; /* unknown modifier type */
288         }
289         add_to_modifier_list(&linestyle->color_modifiers, new_m);
290
291         return new_m;
292 }
293
294 void FRS_remove_linestyle_color_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
295 {
296         switch (m->type) {
297         case LS_MODIFIER_ALONG_STROKE:
298                 MEM_freeN(((LineStyleColorModifier_AlongStroke *)m)->color_ramp);
299                 break;
300         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
301                 MEM_freeN(((LineStyleColorModifier_DistanceFromCamera *)m)->color_ramp);
302                 break;
303         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
304                 MEM_freeN(((LineStyleColorModifier_DistanceFromObject *)m)->color_ramp);
305                 break;
306         case LS_MODIFIER_MATERIAL:
307                 MEM_freeN(((LineStyleColorModifier_Material *)m)->color_ramp);
308                 break;
309         }
310         BLI_freelinkN(&linestyle->color_modifiers, m);
311 }
312
313 static LineStyleModifier *alloc_alpha_modifier(int type)
314 {
315         size_t size;
316
317         switch (type) {
318         case LS_MODIFIER_ALONG_STROKE:
319                 size = sizeof(LineStyleAlphaModifier_AlongStroke);
320                 break;
321         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
322                 size = sizeof(LineStyleAlphaModifier_DistanceFromCamera);
323                 break;
324         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
325                 size = sizeof(LineStyleAlphaModifier_DistanceFromObject);
326                 break;
327         case LS_MODIFIER_MATERIAL:
328                 size = sizeof(LineStyleAlphaModifier_Material);
329                 break;
330         default:
331                 return NULL; /* unknown modifier type */
332         }
333         return new_modifier(type, size);
334 }
335
336 LineStyleModifier *FRS_add_linestyle_alpha_modifier(FreestyleLineStyle *linestyle, int type)
337 {
338         LineStyleModifier *m;
339         
340         m = alloc_alpha_modifier(type);
341         if (!m)
342                 return NULL;
343         m->blend = LS_VALUE_BLEND;
344         switch (type) {
345         case LS_MODIFIER_ALONG_STROKE:
346                 ((LineStyleAlphaModifier_AlongStroke *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
347                 break;
348         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
349                 ((LineStyleAlphaModifier_DistanceFromCamera *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
350                 ((LineStyleAlphaModifier_DistanceFromCamera *)m)->range_min = 0.0f;
351                 ((LineStyleAlphaModifier_DistanceFromCamera *)m)->range_max = 10000.0f;
352                 break;
353         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
354                 ((LineStyleAlphaModifier_DistanceFromObject *)m)->target = NULL;
355                 ((LineStyleAlphaModifier_DistanceFromObject *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
356                 ((LineStyleAlphaModifier_DistanceFromObject *)m)->range_min = 0.0f;
357                 ((LineStyleAlphaModifier_DistanceFromObject *)m)->range_max = 10000.0f;
358                 break;
359         case LS_MODIFIER_MATERIAL:
360                 ((LineStyleAlphaModifier_Material *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
361                 ((LineStyleAlphaModifier_Material *)m)->mat_attr = LS_MODIFIER_MATERIAL_DIFF;
362                 break;
363         default:
364                 return NULL; /* unknown modifier type */
365         }
366         add_to_modifier_list(&linestyle->alpha_modifiers, m);
367
368         return m;
369 }
370
371 LineStyleModifier *FRS_copy_linestyle_alpha_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
372 {
373         LineStyleModifier *new_m;
374         
375         new_m = alloc_alpha_modifier(m->type);
376         if (!new_m)
377                 return NULL;
378         new_m->influence = m->influence;
379         new_m->flags = m->flags;
380         new_m->blend = m->blend;
381         switch (m->type) {
382         case LS_MODIFIER_ALONG_STROKE:
383                 {
384                         LineStyleAlphaModifier_AlongStroke *p = (LineStyleAlphaModifier_AlongStroke *)m;
385                         ((LineStyleAlphaModifier_AlongStroke *)new_m)->curve = curvemapping_copy(p->curve);
386                 }
387                 break;
388         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
389                 {
390                         LineStyleAlphaModifier_DistanceFromCamera *p = (LineStyleAlphaModifier_DistanceFromCamera *)m;
391                         ((LineStyleAlphaModifier_DistanceFromCamera *)new_m)->curve = curvemapping_copy(p->curve);
392                         ((LineStyleAlphaModifier_DistanceFromCamera *)new_m)->range_min = p->range_min;
393                         ((LineStyleAlphaModifier_DistanceFromCamera *)new_m)->range_max = p->range_max;
394                 }
395                 break;
396         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
397                 {
398                         LineStyleAlphaModifier_DistanceFromObject *p = (LineStyleAlphaModifier_DistanceFromObject *)m;
399                         if (p->target)
400                                 p->target->id.us++;
401                         ((LineStyleAlphaModifier_DistanceFromObject *)new_m)->target = p->target;
402                         ((LineStyleAlphaModifier_DistanceFromObject *)new_m)->curve = curvemapping_copy(p->curve);
403                         ((LineStyleAlphaModifier_DistanceFromObject *)new_m)->range_min = p->range_min;
404                         ((LineStyleAlphaModifier_DistanceFromObject *)new_m)->range_max = p->range_max;
405                 }
406                 break;
407         case LS_MODIFIER_MATERIAL:
408                 {
409                         LineStyleAlphaModifier_Material *p = (LineStyleAlphaModifier_Material *)m;
410                         ((LineStyleAlphaModifier_Material *)new_m)->curve = curvemapping_copy(p->curve);
411                         ((LineStyleAlphaModifier_Material *)new_m)->mat_attr = p->mat_attr;
412                 }
413                 break;
414         default:
415                 return NULL; /* unknown modifier type */
416         }
417         add_to_modifier_list(&linestyle->alpha_modifiers, new_m);
418
419         return new_m;
420 }
421
422 void FRS_remove_linestyle_alpha_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
423 {
424         switch (m->type) {
425         case LS_MODIFIER_ALONG_STROKE:
426                 curvemapping_free(((LineStyleAlphaModifier_AlongStroke *)m)->curve);
427                 break;
428         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
429                 curvemapping_free(((LineStyleAlphaModifier_DistanceFromCamera *)m)->curve);
430                 break;
431         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
432                 curvemapping_free(((LineStyleAlphaModifier_DistanceFromObject *)m)->curve);
433                 break;
434         case LS_MODIFIER_MATERIAL:
435                 curvemapping_free(((LineStyleAlphaModifier_Material *)m)->curve);
436                 break;
437         }
438         BLI_freelinkN(&linestyle->alpha_modifiers, m);
439 }
440
441 static LineStyleModifier *alloc_thickness_modifier(int type)
442 {
443         size_t size;
444
445         switch (type) {
446         case LS_MODIFIER_ALONG_STROKE:
447                 size = sizeof(LineStyleThicknessModifier_AlongStroke);
448                 break;
449         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
450                 size = sizeof(LineStyleThicknessModifier_DistanceFromCamera);
451                 break;
452         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
453                 size = sizeof(LineStyleThicknessModifier_DistanceFromObject);
454                 break;
455         case LS_MODIFIER_MATERIAL:
456                 size = sizeof(LineStyleThicknessModifier_Material);
457                 break;
458         case LS_MODIFIER_CALLIGRAPHY:
459                 size = sizeof(LineStyleThicknessModifier_Calligraphy);
460                 break;
461         default:
462                 return NULL; /* unknown modifier type */
463         }
464         return new_modifier(type, size);
465 }
466
467 LineStyleModifier *FRS_add_linestyle_thickness_modifier(FreestyleLineStyle *linestyle, int type)
468 {
469         LineStyleModifier *m;
470
471         m = alloc_thickness_modifier(type);
472         if (!m)
473                 return NULL;
474         m->blend = LS_VALUE_BLEND;
475         switch (type) {
476         case LS_MODIFIER_ALONG_STROKE:
477                 ((LineStyleThicknessModifier_AlongStroke *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
478                 ((LineStyleThicknessModifier_AlongStroke *)m)->value_min = 0.0f;
479                 ((LineStyleThicknessModifier_AlongStroke *)m)->value_max = 1.0f;
480                 break;
481         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
482                 ((LineStyleThicknessModifier_DistanceFromCamera *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
483                 ((LineStyleThicknessModifier_DistanceFromCamera *)m)->range_min = 0.0f;
484                 ((LineStyleThicknessModifier_DistanceFromCamera *)m)->range_max = 1000.0f;
485                 ((LineStyleThicknessModifier_DistanceFromCamera *)m)->value_min = 0.0f;
486                 ((LineStyleThicknessModifier_DistanceFromCamera *)m)->value_max = 1.0f;
487                 break;
488         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
489                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->target = NULL;
490                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
491                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->range_min = 0.0f;
492                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->range_max = 1000.0f;
493                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->value_min = 0.0f;
494                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->value_max = 1.0f;
495                 break;
496         case LS_MODIFIER_MATERIAL:
497                 ((LineStyleThicknessModifier_Material *)m)->curve = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
498                 ((LineStyleThicknessModifier_Material *)m)->mat_attr = LS_MODIFIER_MATERIAL_DIFF;
499                 ((LineStyleThicknessModifier_Material *)m)->value_min = 0.0f;
500                 ((LineStyleThicknessModifier_Material *)m)->value_max = 1.0f;
501                 break;
502         case LS_MODIFIER_CALLIGRAPHY:
503                 ((LineStyleThicknessModifier_Calligraphy *)m)->min_thickness = 1.0f;
504                 ((LineStyleThicknessModifier_Calligraphy *)m)->max_thickness = 10.0f;
505                 ((LineStyleThicknessModifier_Calligraphy *)m)->orientation = 60.0f;
506                 break;
507         default:
508                 return NULL; /* unknown modifier type */
509         }
510         add_to_modifier_list(&linestyle->thickness_modifiers, m);
511
512         return m;
513 }
514
515 LineStyleModifier *FRS_copy_linestyle_thickness_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
516 {
517         LineStyleModifier *new_m;
518
519         new_m = alloc_thickness_modifier(m->type);
520         if (!new_m)
521                 return NULL;
522         new_m->influence = m->influence;
523         new_m->flags = m->flags;
524         new_m->blend = m->blend;
525         switch (m->type) {
526         case LS_MODIFIER_ALONG_STROKE:
527                 {
528                         LineStyleThicknessModifier_AlongStroke *p = (LineStyleThicknessModifier_AlongStroke *)m;
529                         ((LineStyleThicknessModifier_AlongStroke *)new_m)->curve = curvemapping_copy(p->curve);
530                         ((LineStyleThicknessModifier_AlongStroke *)new_m)->value_min = p->value_min;
531                         ((LineStyleThicknessModifier_AlongStroke *)new_m)->value_max = p->value_max;
532                 }
533                 break;
534         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
535                 {
536                         LineStyleThicknessModifier_DistanceFromCamera *p = (LineStyleThicknessModifier_DistanceFromCamera *)m;
537                         ((LineStyleThicknessModifier_DistanceFromCamera *)new_m)->curve = curvemapping_copy(p->curve);
538                         ((LineStyleThicknessModifier_DistanceFromCamera *)new_m)->range_min = p->range_min;
539                         ((LineStyleThicknessModifier_DistanceFromCamera *)new_m)->range_max = p->range_max;
540                         ((LineStyleThicknessModifier_DistanceFromCamera *)new_m)->value_min = p->value_min;
541                         ((LineStyleThicknessModifier_DistanceFromCamera *)new_m)->value_max = p->value_max;
542                 }
543                 break;
544         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
545                 {
546                         LineStyleThicknessModifier_DistanceFromObject *p = (LineStyleThicknessModifier_DistanceFromObject *)m;
547                         if (p->target)
548                                 p->target->id.us++;
549                         ((LineStyleThicknessModifier_DistanceFromObject *)new_m)->target = p->target;
550                         ((LineStyleThicknessModifier_DistanceFromObject *)new_m)->curve = curvemapping_copy(p->curve);
551                         ((LineStyleThicknessModifier_DistanceFromObject *)new_m)->range_min = p->range_min;
552                         ((LineStyleThicknessModifier_DistanceFromObject *)new_m)->range_max = p->range_max;
553                         ((LineStyleThicknessModifier_DistanceFromObject *)new_m)->value_min = p->value_min;
554                         ((LineStyleThicknessModifier_DistanceFromObject *)new_m)->value_max = p->value_max;
555                 }
556                 break;
557         case LS_MODIFIER_MATERIAL:
558                 {
559                         LineStyleThicknessModifier_Material *p = (LineStyleThicknessModifier_Material *)m;
560                         ((LineStyleThicknessModifier_Material *)new_m)->curve = curvemapping_copy(p->curve);
561                         ((LineStyleThicknessModifier_Material *)new_m)->mat_attr = p->mat_attr;
562                         ((LineStyleThicknessModifier_Material *)new_m)->value_min = p->value_min;
563                         ((LineStyleThicknessModifier_Material *)new_m)->value_max = p->value_max;
564                 }
565                 break;
566         case LS_MODIFIER_CALLIGRAPHY:
567                 {
568                         LineStyleThicknessModifier_Calligraphy *p = (LineStyleThicknessModifier_Calligraphy *)m;
569                         ((LineStyleThicknessModifier_Calligraphy *)new_m)->min_thickness = p->min_thickness;
570                         ((LineStyleThicknessModifier_Calligraphy *)new_m)->max_thickness = p->max_thickness;
571                         ((LineStyleThicknessModifier_Calligraphy *)new_m)->orientation = p->orientation;
572                 }
573                 break;
574         default:
575                 return NULL; /* unknown modifier type */
576         }
577         add_to_modifier_list(&linestyle->thickness_modifiers, new_m);
578
579         return new_m;
580 }
581
582 void FRS_remove_linestyle_thickness_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
583 {
584         switch (m->type) {
585         case LS_MODIFIER_ALONG_STROKE:
586                 curvemapping_free(((LineStyleThicknessModifier_AlongStroke *)m)->curve);
587                 break;
588         case LS_MODIFIER_DISTANCE_FROM_CAMERA:
589                 curvemapping_free(((LineStyleThicknessModifier_DistanceFromCamera *)m)->curve);
590                 break;
591         case LS_MODIFIER_DISTANCE_FROM_OBJECT:
592                 curvemapping_free(((LineStyleThicknessModifier_DistanceFromObject *)m)->curve);
593                 break;
594         case LS_MODIFIER_MATERIAL:
595                 curvemapping_free(((LineStyleThicknessModifier_Material *)m)->curve);
596                 break;
597         case LS_MODIFIER_CALLIGRAPHY:
598                 break;
599         }
600         BLI_freelinkN(&linestyle->thickness_modifiers, m);
601 }
602
603 static LineStyleModifier *alloc_geometry_modifier(int type)
604 {
605         size_t size;
606
607         switch (type) {
608         case LS_MODIFIER_SAMPLING:
609                 size = sizeof(LineStyleGeometryModifier_Sampling);
610                 break;
611         case LS_MODIFIER_BEZIER_CURVE:
612                 size = sizeof(LineStyleGeometryModifier_BezierCurve);
613                 break;
614         case LS_MODIFIER_SINUS_DISPLACEMENT:
615                 size = sizeof(LineStyleGeometryModifier_SinusDisplacement);
616                 break;
617         case LS_MODIFIER_SPATIAL_NOISE:
618                 size = sizeof(LineStyleGeometryModifier_SpatialNoise);
619                 break;
620         case LS_MODIFIER_PERLIN_NOISE_1D:
621                 size = sizeof(LineStyleGeometryModifier_PerlinNoise1D);
622                 break;
623         case LS_MODIFIER_PERLIN_NOISE_2D:
624                 size = sizeof(LineStyleGeometryModifier_PerlinNoise2D);
625                 break;
626         case LS_MODIFIER_BACKBONE_STRETCHER:
627                 size = sizeof(LineStyleGeometryModifier_BackboneStretcher);
628                 break;
629         case LS_MODIFIER_TIP_REMOVER:
630                 size = sizeof(LineStyleGeometryModifier_TipRemover);
631                 break;
632         case LS_MODIFIER_POLYGONIZATION:
633                 size = sizeof(LineStyleGeometryModifier_Polygonalization);
634                 break;
635         case LS_MODIFIER_GUIDING_LINES:
636                 size = sizeof(LineStyleGeometryModifier_GuidingLines);
637                 break;
638         case LS_MODIFIER_BLUEPRINT:
639                 size = sizeof(LineStyleGeometryModifier_Blueprint);
640                 break;
641         case LS_MODIFIER_2D_OFFSET:
642                 size = sizeof(LineStyleGeometryModifier_2DOffset);
643                 break;
644         case LS_MODIFIER_2D_TRANSFORM:
645                 size = sizeof(LineStyleGeometryModifier_2DTransform);
646                 break;
647         default:
648                 return NULL; /* unknown modifier type */
649         }
650         return new_modifier(type, size);
651 }
652
653 LineStyleModifier *FRS_add_linestyle_geometry_modifier(FreestyleLineStyle *linestyle, int type)
654 {
655         LineStyleModifier *m;
656
657         m = alloc_geometry_modifier(type);
658         if (!m)
659                 return NULL;
660         switch (type) {
661         case LS_MODIFIER_SAMPLING:
662                 ((LineStyleGeometryModifier_Sampling *)m)->sampling = 10.0;
663                 break;
664         case LS_MODIFIER_BEZIER_CURVE:
665                 ((LineStyleGeometryModifier_BezierCurve *)m)->error = 10.0;
666                 break;
667         case LS_MODIFIER_SINUS_DISPLACEMENT:
668                 ((LineStyleGeometryModifier_SinusDisplacement *)m)->wavelength = 20.0;
669                 ((LineStyleGeometryModifier_SinusDisplacement *)m)->amplitude = 5.0;
670                 ((LineStyleGeometryModifier_SinusDisplacement *)m)->phase = 0.0;
671                 break;
672         case LS_MODIFIER_SPATIAL_NOISE:
673                 ((LineStyleGeometryModifier_SpatialNoise *)m)->amplitude = 5.0;
674                 ((LineStyleGeometryModifier_SpatialNoise *)m)->scale = 20.0;
675                 ((LineStyleGeometryModifier_SpatialNoise *)m)->octaves = 4;
676                 ((LineStyleGeometryModifier_SpatialNoise *)m)->flags = LS_MODIFIER_SPATIAL_NOISE_SMOOTH | LS_MODIFIER_SPATIAL_NOISE_PURERANDOM;
677                 break;
678         case LS_MODIFIER_PERLIN_NOISE_1D:
679                 ((LineStyleGeometryModifier_PerlinNoise1D *)m)->frequency = 10.0;
680                 ((LineStyleGeometryModifier_PerlinNoise1D *)m)->amplitude = 10.0;
681                 ((LineStyleGeometryModifier_PerlinNoise1D *)m)->octaves = 4;
682                 ((LineStyleGeometryModifier_PerlinNoise1D *)m)->angle = 45.0;
683                 break;
684         case LS_MODIFIER_PERLIN_NOISE_2D:
685                 ((LineStyleGeometryModifier_PerlinNoise2D *)m)->frequency = 10.0;
686                 ((LineStyleGeometryModifier_PerlinNoise2D *)m)->amplitude = 10.0;
687                 ((LineStyleGeometryModifier_PerlinNoise2D *)m)->octaves = 4;
688                 ((LineStyleGeometryModifier_PerlinNoise2D *)m)->angle = 45.0;
689                 break;
690         case LS_MODIFIER_BACKBONE_STRETCHER:
691                 ((LineStyleGeometryModifier_BackboneStretcher *)m)->backbone_length = 10.0;
692                 break;
693         case LS_MODIFIER_TIP_REMOVER:
694                 ((LineStyleGeometryModifier_TipRemover *)m)->tip_length = 10.0;
695                 break;
696         case LS_MODIFIER_POLYGONIZATION:
697                 ((LineStyleGeometryModifier_Polygonalization *)m)->error = 10.0;
698                 break;
699         case LS_MODIFIER_GUIDING_LINES:
700                 ((LineStyleGeometryModifier_GuidingLines *)m)->offset = 0.0;
701                 break;
702         case LS_MODIFIER_BLUEPRINT:
703                 ((LineStyleGeometryModifier_Blueprint *)m)->flags = LS_MODIFIER_BLUEPRINT_CIRCLES;
704                 ((LineStyleGeometryModifier_Blueprint *)m)->rounds = 1;
705                 ((LineStyleGeometryModifier_Blueprint *)m)->backbone_length = 10.f;
706                 ((LineStyleGeometryModifier_Blueprint *)m)->random_radius = 3;
707                 ((LineStyleGeometryModifier_Blueprint *)m)->random_center = 5;
708                 ((LineStyleGeometryModifier_Blueprint *)m)->random_backbone = 5;
709                 break;
710         case LS_MODIFIER_2D_OFFSET:
711                 ((LineStyleGeometryModifier_2DOffset *)m)->start = 0.f;
712                 ((LineStyleGeometryModifier_2DOffset *)m)->end = 0.f;
713                 ((LineStyleGeometryModifier_2DOffset *)m)->x = 0.f;
714                 ((LineStyleGeometryModifier_2DOffset *)m)->y = 0.f;
715                 break;
716         case LS_MODIFIER_2D_TRANSFORM:
717                 ((LineStyleGeometryModifier_2DTransform *)m)->pivot = LS_MODIFIER_2D_TRANSFORM_PIVOT_CENTER;
718                 ((LineStyleGeometryModifier_2DTransform *)m)->scale_x = 1.f;
719                 ((LineStyleGeometryModifier_2DTransform *)m)->scale_y = 1.f;
720                 ((LineStyleGeometryModifier_2DTransform *)m)->angle = 0.f;
721                 ((LineStyleGeometryModifier_2DTransform *)m)->pivot_u = 0.5f;
722                 ((LineStyleGeometryModifier_2DTransform *)m)->pivot_x = 0.f;
723                 ((LineStyleGeometryModifier_2DTransform *)m)->pivot_y = 0.f;
724                 break;
725         default:
726                 return NULL; /* unknown modifier type */
727         }
728         add_to_modifier_list(&linestyle->geometry_modifiers, m);
729
730         return m;
731 }
732
733 LineStyleModifier *FRS_copy_linestyle_geometry_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
734 {
735         LineStyleModifier *new_m;
736
737         new_m = alloc_geometry_modifier(m->type);
738         if (!new_m)
739                 return NULL;
740         new_m->flags = m->flags;
741         switch (m->type) {
742         case LS_MODIFIER_SAMPLING:
743                 {
744                         LineStyleGeometryModifier_Sampling *p = (LineStyleGeometryModifier_Sampling *)m;
745                         ((LineStyleGeometryModifier_Sampling *)new_m)->sampling = p->sampling;
746                 }
747                 break;
748         case LS_MODIFIER_BEZIER_CURVE:
749                 {
750                         LineStyleGeometryModifier_BezierCurve *p = (LineStyleGeometryModifier_BezierCurve *)m;
751                         ((LineStyleGeometryModifier_BezierCurve *)new_m)->error = p->error;
752                 }
753                 break;
754         case LS_MODIFIER_SINUS_DISPLACEMENT:
755                 {
756                         LineStyleGeometryModifier_SinusDisplacement *p = (LineStyleGeometryModifier_SinusDisplacement *)m;
757                         ((LineStyleGeometryModifier_SinusDisplacement *)new_m)->wavelength = p->wavelength;
758                         ((LineStyleGeometryModifier_SinusDisplacement *)new_m)->amplitude = p->amplitude;
759                         ((LineStyleGeometryModifier_SinusDisplacement *)new_m)->phase = p->phase;
760                 }
761                 break;
762         case LS_MODIFIER_SPATIAL_NOISE:
763                 {
764                         LineStyleGeometryModifier_SpatialNoise *p = (LineStyleGeometryModifier_SpatialNoise *)m;
765                         ((LineStyleGeometryModifier_SpatialNoise *)new_m)->amplitude = p->amplitude;
766                         ((LineStyleGeometryModifier_SpatialNoise *)new_m)->scale = p->scale;
767                         ((LineStyleGeometryModifier_SpatialNoise *)new_m)->octaves = p->octaves;
768                         ((LineStyleGeometryModifier_SpatialNoise *)new_m)->flags = p->flags;
769                 }
770                 break;
771         case LS_MODIFIER_PERLIN_NOISE_1D:
772                 {
773                         LineStyleGeometryModifier_PerlinNoise1D *p = (LineStyleGeometryModifier_PerlinNoise1D *)m;
774                         ((LineStyleGeometryModifier_PerlinNoise1D *)new_m)->frequency = p->frequency;
775                         ((LineStyleGeometryModifier_PerlinNoise1D *)new_m)->amplitude = p->amplitude;
776                         ((LineStyleGeometryModifier_PerlinNoise1D *)new_m)->octaves = p->octaves;
777                         ((LineStyleGeometryModifier_PerlinNoise1D *)new_m)->angle = p->angle;
778                 }
779                 break;
780         case LS_MODIFIER_PERLIN_NOISE_2D:
781                 {
782                         LineStyleGeometryModifier_PerlinNoise2D *p = (LineStyleGeometryModifier_PerlinNoise2D *)m;
783                         ((LineStyleGeometryModifier_PerlinNoise2D *)new_m)->frequency = p->frequency;
784                         ((LineStyleGeometryModifier_PerlinNoise2D *)new_m)->amplitude = p->amplitude;
785                         ((LineStyleGeometryModifier_PerlinNoise2D *)new_m)->octaves = p->octaves;
786                         ((LineStyleGeometryModifier_PerlinNoise2D *)new_m)->angle = p->angle;
787                 }
788                 break;
789         case LS_MODIFIER_BACKBONE_STRETCHER:
790                 {
791                         LineStyleGeometryModifier_BackboneStretcher *p = (LineStyleGeometryModifier_BackboneStretcher *)m;
792                         ((LineStyleGeometryModifier_BackboneStretcher *)new_m)->backbone_length = p->backbone_length;
793                 }
794                 break;
795         case LS_MODIFIER_TIP_REMOVER:
796                 {
797                         LineStyleGeometryModifier_TipRemover *p = (LineStyleGeometryModifier_TipRemover *)m;
798                         ((LineStyleGeometryModifier_TipRemover *)new_m)->tip_length = p->tip_length;
799                 }
800                 break;
801         case LS_MODIFIER_POLYGONIZATION:
802                 {
803                         LineStyleGeometryModifier_Polygonalization *p = (LineStyleGeometryModifier_Polygonalization *)m;
804                         ((LineStyleGeometryModifier_Polygonalization *)new_m)->error = p->error;
805                 }
806                 break;
807         case LS_MODIFIER_GUIDING_LINES:
808                 {
809                         LineStyleGeometryModifier_GuidingLines *p = (LineStyleGeometryModifier_GuidingLines *)m;
810                         ((LineStyleGeometryModifier_GuidingLines *)new_m)->offset = p->offset;
811                 }
812                 break;
813         case LS_MODIFIER_BLUEPRINT:
814                 {
815                         LineStyleGeometryModifier_Blueprint *p = (LineStyleGeometryModifier_Blueprint *)m;
816                         ((LineStyleGeometryModifier_Blueprint *)new_m)->flags = p->flags;
817                         ((LineStyleGeometryModifier_Blueprint *)new_m)->rounds = p->rounds;
818                         ((LineStyleGeometryModifier_Blueprint *)new_m)->backbone_length = p->backbone_length;
819                         ((LineStyleGeometryModifier_Blueprint *)new_m)->random_radius = p->random_radius;
820                         ((LineStyleGeometryModifier_Blueprint *)new_m)->random_center = p->random_center;
821                         ((LineStyleGeometryModifier_Blueprint *)new_m)->random_backbone = p->random_backbone;
822                 }
823                 break;
824         case LS_MODIFIER_2D_OFFSET:
825                 {
826                         LineStyleGeometryModifier_2DOffset *p = (LineStyleGeometryModifier_2DOffset *)m;
827                         ((LineStyleGeometryModifier_2DOffset *)new_m)->start = p->start;
828                         ((LineStyleGeometryModifier_2DOffset *)new_m)->end = p->end;
829                         ((LineStyleGeometryModifier_2DOffset *)new_m)->x = p->x;
830                         ((LineStyleGeometryModifier_2DOffset *)new_m)->y = p->y;
831                 }
832                 break;
833         case LS_MODIFIER_2D_TRANSFORM:
834                 {
835                         LineStyleGeometryModifier_2DTransform *p = (LineStyleGeometryModifier_2DTransform *)m;
836                         ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot = p->pivot;
837                         ((LineStyleGeometryModifier_2DTransform *)new_m)->scale_x = p->scale_x;
838                         ((LineStyleGeometryModifier_2DTransform *)new_m)->scale_y = p->scale_y;
839                         ((LineStyleGeometryModifier_2DTransform *)new_m)->angle = p->angle;
840                         ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot_u = p->pivot_u;
841                         ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot_x = p->pivot_x;
842                         ((LineStyleGeometryModifier_2DTransform *)new_m)->pivot_y = p->pivot_y;
843                 }
844                 break;
845         default:
846                 return NULL; /* unknown modifier type */
847         }
848         add_to_modifier_list(&linestyle->geometry_modifiers, new_m);
849
850         return new_m;
851 }
852
853 void FRS_remove_linestyle_geometry_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *m)
854 {
855         switch (m->type) {
856         case LS_MODIFIER_SAMPLING:
857                 break;
858         case LS_MODIFIER_BEZIER_CURVE:
859                 break;
860         case LS_MODIFIER_SINUS_DISPLACEMENT:
861                 break;
862         case LS_MODIFIER_SPATIAL_NOISE:
863                 break;
864         case LS_MODIFIER_PERLIN_NOISE_1D:
865                 break;
866         case LS_MODIFIER_PERLIN_NOISE_2D:
867                 break;
868         case LS_MODIFIER_BACKBONE_STRETCHER:
869                 break;
870         case LS_MODIFIER_TIP_REMOVER:
871                 break;
872         case LS_MODIFIER_POLYGONIZATION:
873                 break;
874         case LS_MODIFIER_GUIDING_LINES:
875                 break;
876         case LS_MODIFIER_BLUEPRINT:
877                 break;
878         case LS_MODIFIER_2D_OFFSET:
879                 break;
880         case LS_MODIFIER_2D_TRANSFORM:
881                 break;
882         }
883         BLI_freelinkN(&linestyle->geometry_modifiers, m);
884 }
885
886 static void move_modifier(ListBase *lb, LineStyleModifier *modifier, int direction)
887 {
888         BLI_remlink(lb, modifier);
889         if (direction > 0)
890                 BLI_insertlinkbefore(lb, modifier->prev, modifier);
891         else
892                 BLI_insertlinkafter(lb, modifier->next, modifier);
893 }
894
895 void FRS_move_linestyle_color_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
896 {
897         move_modifier(&linestyle->color_modifiers, modifier, direction);
898 }
899
900 void FRS_move_linestyle_alpha_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
901 {
902         move_modifier(&linestyle->alpha_modifiers, modifier, direction);
903 }
904
905 void FRS_move_linestyle_thickness_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
906 {
907         move_modifier(&linestyle->thickness_modifiers, modifier, direction);
908 }
909
910 void FRS_move_linestyle_geometry_modifier(FreestyleLineStyle *linestyle, LineStyleModifier *modifier, int direction)
911 {
912         move_modifier(&linestyle->geometry_modifiers, modifier, direction);
913 }
914
915 void FRS_list_modifier_color_ramps(FreestyleLineStyle *linestyle, ListBase *listbase)
916 {
917         LineStyleModifier *m;
918         ColorBand *color_ramp;
919         LinkData *link;
920
921         listbase->first = listbase->last = NULL;
922         for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next) {
923                 switch (m->type) {
924                 case LS_MODIFIER_ALONG_STROKE:
925                         color_ramp = ((LineStyleColorModifier_AlongStroke *)m)->color_ramp;
926                         break;
927                 case LS_MODIFIER_DISTANCE_FROM_CAMERA:
928                         color_ramp = ((LineStyleColorModifier_DistanceFromCamera *)m)->color_ramp;
929                         break;
930                 case LS_MODIFIER_DISTANCE_FROM_OBJECT:
931                         color_ramp = ((LineStyleColorModifier_DistanceFromObject *)m)->color_ramp;
932                         break;
933                 case LS_MODIFIER_MATERIAL:
934                         color_ramp = ((LineStyleColorModifier_Material *)m)->color_ramp;
935                         break;
936                 default:
937                         continue;
938                 }
939                 link = (LinkData *) MEM_callocN( sizeof(LinkData), "link to color ramp");
940                 link->data = color_ramp;
941                 BLI_addtail(listbase, link);
942         }
943 }
944
945 char *FRS_path_from_ID_to_color_ramp(FreestyleLineStyle *linestyle, ColorBand *color_ramp)
946 {
947         LineStyleModifier *m;
948
949         for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next) {
950                 switch (m->type) {
951                 case LS_MODIFIER_ALONG_STROKE:
952                         if (color_ramp == ((LineStyleColorModifier_AlongStroke *)m)->color_ramp)
953                                 goto found;
954                         break;
955                 case LS_MODIFIER_DISTANCE_FROM_CAMERA:
956                         if (color_ramp == ((LineStyleColorModifier_DistanceFromCamera *)m)->color_ramp)
957                                 goto found;
958                         break;
959                 case LS_MODIFIER_DISTANCE_FROM_OBJECT:
960                         if (color_ramp == ((LineStyleColorModifier_DistanceFromObject *)m)->color_ramp)
961                                 goto found;
962                         break;
963                 case LS_MODIFIER_MATERIAL:
964                         if (color_ramp == ((LineStyleColorModifier_Material *)m)->color_ramp)
965                                 goto found;
966                         break;
967                 }
968         }
969         printf("FRS_path_from_ID_to_color_ramp: No color ramps correspond to the given pointer.\n");
970         return NULL;
971
972 found:
973         return BLI_sprintfN("color_modifiers[\"%s\"].color_ramp", m->name);
974 }
975
976 void FRS_unlink_linestyle_target_object(FreestyleLineStyle *linestyle, struct Object *ob)
977 {
978         LineStyleModifier *m;
979
980         for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next) {
981                 if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
982                         if (((LineStyleColorModifier_DistanceFromObject *)m)->target == ob) {
983                                 ((LineStyleColorModifier_DistanceFromObject *)m)->target = NULL;
984                         }
985                 }
986         }
987         for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next) {
988                 if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
989                         if (((LineStyleAlphaModifier_DistanceFromObject *)m)->target == ob) {
990                                 ((LineStyleAlphaModifier_DistanceFromObject *)m)->target = NULL;
991                         }
992                 }
993         }
994         for (m = (LineStyleModifier *)linestyle->thickness_modifiers.first; m; m = m->next) {
995                 if (m->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
996                         if (((LineStyleThicknessModifier_DistanceFromObject *)m)->target == ob) {
997                                 ((LineStyleThicknessModifier_DistanceFromObject *)m)->target = NULL;
998                         }
999                 }
1000         }
1001 }