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