changed empty #elif to #else
[blender.git] / source / blender / src / drawdeps.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2004 Blender Foundation.
24  * All rights reserved.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <math.h>
34
35 #ifdef _WIN32
36 #include "BLI_winstuff.h"
37 #endif
38
39 #include "BMF_Api.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_arithb.h"
43
44 #include "DNA_ID.h"
45 #include "DNA_object_types.h"
46 #include "DNA_oops_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_space_types.h"
50 #include "DNA_view2d_types.h"
51 #include "DNA_action_types.h"
52
53 #include "BKE_utildefines.h"
54 #include "BKE_global.h"
55
56 #include "BIF_interface.h"
57 #include "BIF_gl.h"
58 #include "BIF_glutil.h"
59 #include "BIF_mywindow.h"
60 #include "BIF_resources.h"
61 #include "BIF_screen.h"
62
63 #include "BIF_oops.h"
64
65 #include "BSE_drawipo.h"
66 #include "BSE_drawoops.h"
67 #include "MEM_guardedalloc.h"
68 #include "blendef.h"
69
70
71 #include "depsgraph_private.h"
72
73 #ifdef WIN32
74 #else
75 #include <sys/time.h>
76 #endif
77
78
79
80 void boundbox_deps()
81 {
82         DagNode *node;
83         float min[2], max[2];
84         
85         if(G.soops==0) return;
86         
87         min[0]= 1000.0;
88         max[0]= -10000.0;
89         min[1]= 1000.0;
90         max[1]= -1000.0;
91         
92         node = getMainDag()->DagNode.first;
93         while(node) {
94                 min[0]= MIN2(min[0], node->x);
95                 max[0]= MAX2(max[0], node->x+OOPSX);
96                 min[1]= MIN2(min[1], node->y);
97                 max[1]= MAX2(max[1], node->y+OOPSY);
98                 
99                 node= node->next;
100         }
101                 
102         G.v2d->tot.xmin= min[0];
103         G.v2d->tot.xmax= max[0];
104         G.v2d->tot.ymin= min[1];
105         G.v2d->tot.ymax= max[1];
106 }
107
108 static unsigned int get_line_color(DagAdjList *child)
109 {
110         switch  (child->type) {
111                 case DAG_RL_SCENE :
112                         return 0x00000;
113                 case DAG_RL_DATA :
114                         return 0xFF0000;
115                 case DAG_RL_PARENT :
116                         return 0x00FF00;
117                 case DAG_RL_TRACK :
118                         return 0xFFFF00;
119                 case DAG_RL_PATH :
120                         return 0x000000;
121                 case DAG_RL_CONSTRAINT :
122                         return 0x0000FF;
123                 case DAG_RL_HOOK :
124                         return 0x00FFFF;
125                 case DAG_RL_DATA_CONSTRAINT :
126                         return 0x0000FF;
127                 default :
128                         return 0x0000FF;
129         }
130         //return 0x00000;
131 }
132
133
134 static void draw_deps(DagNode *node)
135 {
136         float v1[2], x1, y1, x2, y2;
137         unsigned int body, border;
138         short line= 0;
139         char str[32];
140         DagAdjList *itA = node->child;
141
142         x1= node->x; 
143         x2= node->x+DEPSX;
144         y1= node->y; 
145         y2= node->y+DEPSY;
146
147         if(x2 < G.v2d->cur.xmin || x1 > G.v2d->cur.xmax) return;
148         if(y2 < G.v2d->cur.ymin || y1 > G.v2d->cur.ymax) return;
149
150         body =  give_oops_color(node->type, 0, &border);
151
152         line= 0;
153 //      border= 00;
154         cpack(body);
155
156         glRectf(x1,  y1,  x2,  y2);
157         
158         v1[0]= x1; 
159         v1[1]= (y1+y2)/2 -0.3;
160         sprintf(str, "     %s", ((ID *) node->ob)->name+2);
161         
162         calc_oopstext(str, v1);
163         
164                 /* ICON */
165 //      if(str[1] && oopscalex>1.1) {
166         draw_icon_oops(v1, node->type);
167 //      }
168
169         
170         cpack(0x0);
171         glRasterPos3f(v1[0],  v1[1], 0.0);
172         BMF_DrawString(G.fonts, str);
173
174         
175         if(line) setlinestyle(2);
176         cpack(border);
177
178         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
179         glRectf(x1,  y1,  x2,  y2);
180         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
181         if(line) setlinestyle(0);
182
183         while (itA) { /* draw connection lines */
184                 cpack(get_line_color(itA));
185                 glBegin(GL_LINE_STRIP);
186                         glVertex2f(node->x+DEPSX, node->y+ 0.5*DEPSY);
187                         glVertex2f(itA->node->x, itA->node->y+ 0.5*DEPSY);                      
188                 glEnd();
189                 itA = itA->next;
190         }
191                         /* Draw the little rounded connection point */
192                 glColor3ub(0, 0, 0);
193                 glPushMatrix();
194
195                 glTranslatef(node->x , node->y+ 0.5*DEPSY, 0.0);
196                 glutil_draw_filled_arc(-M_PI/2, M_PI, 0.07*DEPSX, 7);
197
198                 glPopMatrix();
199
200 }
201
202 void    draw_all_deps(void)
203 {
204         DagNode *node;
205         DagForest *dag;
206         
207         dag = getMainDag();
208          node = dag->DagNode.first;
209         //node = node->next;
210         while(node) {
211                 draw_deps(node);
212                 node = node->next;
213         }
214         free_forest(dag);
215         MEM_freeN(dag);
216         setMainDag(NULL);
217 }
218
219
220
221
222 int build_deps(short mask)
223 {
224         Base *base;
225         Object *ob = NULL;
226         DagNode * node = NULL; 
227         DagNode * node2 = NULL ;
228         DagNode * node3 = NULL;
229 DagNode * scenenode;
230         DagForest *dag;
231
232 #ifdef DEPS_DEBUG
233         //timers
234         struct timeval tp1, tp2, tp3, tp4;
235         
236         gettimeofday(&tp1,NULL);
237 #endif
238         
239         DagNodeQueue *retqueue;
240         
241 //      float y = 0;
242 //      int maxlev = 0;
243
244         if(G.soops==0) return -1;
245         
246         
247         // rebuilt each time for now
248         dag = getMainDag();
249         if ( dag)
250                 free_forest( dag ); 
251         else {
252                 dag = dag_init();
253                 setMainDag(dag);
254                 }
255                 
256         // add base node for scene. scene is always the first node in DAG
257         scenenode = dag_add_node(dag, G.scene);
258         set_node_xy(scenenode,0.0, 0.0);        
259                 /* blocks from this scene */
260                 
261                 
262                 /* targets in object struct yet to be added. should even they ?
263                                 struct Ipo *ipo;
264                         ListBase nlastrips;
265                         ListBase hooks;
266                 */
267                 
268                 
269         base= FIRSTBASE;
270         while(base) { // add all objects in any case
271                 int addtoroot = 1;
272                 
273 //                               graph_print_adj_list();
274 ob= (Object *) base->object;
275
276                 node = dag_get_node(dag,ob);
277         
278                 if ((ob->data) && (mask&DAG_RL_DATA_MASK)) {
279                         node2 = dag_get_node(dag,ob->data);
280                         dag_add_relation(dag,node,node2,DAG_RL_DATA);
281                         node2->first_ancestor = ob;
282                         node2->ancestor_count += 1;
283                         
284                         if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) { // add armature constraints to datas
285                                 if (ob->pose){
286                                         bPoseChannel *pchan;
287                                         bConstraint *con;
288                                         Object * target;
289                                         
290                                         for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
291                                                 for (con = pchan->constraints.first; con; con=con->next){
292                                                         if (constraint_has_target(con)) {
293                                                                 target = get_constraint_target(con);
294                                                                 if (strcmp(target->id.name, ob->id.name) != 0) {
295                                                                         //fprintf(stderr,"armature target :%s \n", target->id.name);
296                                                                         node3 = dag_get_node(dag,target);
297                                                                         dag_add_relation(dag,node3,node2,DAG_RL_CONSTRAINT);
298                                                                 }
299                                                         }
300                                                 }
301                                         }
302                                 }
303                         }
304                         
305                         if (ob->hooks.first) {
306                                 ObHook *hook;
307                                 
308                                 for(hook= ob->hooks.first; hook; hook= hook->next) {
309                                         if(hook->parent) {
310                                                 node3 = dag_get_node(dag,hook->parent);
311                                                 dag_add_relation(dag,node3,node2,DAG_RL_HOOK);
312                                         }
313                                 }
314                         }
315                 } else { // add armature constraints to object itself
316                         if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) {
317                                 if (ob->pose){
318                                         bPoseChannel *pchan;
319                                         bConstraint *con;
320                                         Object * target;
321                                         
322                                         for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
323                                                 for (con = pchan->constraints.first; con; con=con->next){
324                                                         if (constraint_has_target(con)) {
325                                                                 target = get_constraint_target(con);
326                                                                 if (strcmp(target->id.name, ob->id.name) != 0) {
327                                                                         //fprintf(stderr,"armature target :%s \n", target->id.name);
328                                                                         node3 = dag_get_node(dag,target);
329                                                                         dag_add_relation(dag,node3,node,DAG_RL_CONSTRAINT);
330                                                                 }
331                                                         }
332                                                 }
333                                         }
334                                 }
335                         }
336                         if (ob->hooks.first) {
337                                 ObHook *hook;
338                                 
339                                 for(hook= ob->hooks.first; hook; hook= hook->next) {
340                                         if(hook->parent) {
341                                                 node3 = dag_get_node(dag,hook->parent);
342                                                 dag_add_relation(dag,node3,node,DAG_RL_HOOK);
343                                         }
344                                 }
345                         }                       
346                 }
347
348                 if ((ob->parent) && (mask&DAG_RL_PARENT_MASK)){
349                         node2 = dag_get_node(dag,ob->parent);
350                         dag_add_relation(dag,node2,node,DAG_RL_PARENT);
351                         addtoroot = 0;
352                 }
353                 if ((ob->track) && (mask&DAG_RL_TRACK_MASK)){
354                         node2 = dag_get_node(dag,ob->track);
355                         dag_add_relation(dag,node2,node,DAG_RL_TRACK);
356                         addtoroot = 0;
357
358                 }
359                 if ((ob->path) && (mask&DAG_RL_PATH_MASK)){
360                         node2 = dag_get_node(dag,ob->track);
361                         dag_add_relation(dag,node2,node,DAG_RL_PATH);
362                         addtoroot = 0;
363
364                 }
365
366                 /* Count constraints */
367                 if (mask & DAG_RL_CONSTRAINT_MASK) {
368                         bConstraint *con;
369                         for (con = ob->constraints.first; con; con=con->next){
370                                 if (constraint_has_target(con)) {
371                                         node2 = dag_get_node(dag,get_constraint_target(con));
372                                         dag_add_relation(dag,node2,node,DAG_RL_CONSTRAINT);
373                                         addtoroot = 0;
374                                         
375                                 }
376                         }
377                 }       
378                 
379                 
380                 if (addtoroot == 1 )
381                         dag_add_relation(dag,scenenode,node,DAG_RL_SCENE);
382
383                 addtoroot = 1;
384                 base= base->next;
385         }
386
387 //graph_print_adj_list();
388 //fprintf(stderr,"building deps\n");
389 #ifdef DEPS_DEBUG
390         gettimeofday(&tp2,NULL);
391 #endif
392
393 //graph_bfs(); //set levels
394
395 #ifdef DEPS_DEBUG
396 gettimeofday(&tp3,NULL);
397 #endif
398
399
400 retqueue = graph_dfs(); //set levels
401 #ifdef DEPS_DEBUG
402 gettimeofday(&tp4,NULL);
403 fprintf(stderr,"************************************\n");
404 graph_print_queue_dist(retqueue);
405 //graph_print_queue(retqueue);
406
407 fprintf(stderr,"TIME BUILD %d %d BFS %d %d DFS  %d %d\n",tp2.tv_sec-tp1.tv_sec ,tp2.tv_usec-tp1.tv_usec
408                                                                                                                 , tp3.tv_sec-tp2.tv_sec ,tp3.tv_usec-tp2.tv_usec
409                                                                                                                 , tp4.tv_sec-tp3.tv_sec ,tp4.tv_usec-tp3.tv_usec);
410 #endif
411
412 queue_delete(retqueue);
413
414 //graph_print_adj_list();
415 return 0;
416 }