Revision: 27502
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27502
Author:   blendix
Date:     2010-03-14 23:30:57 +0100 (Sun, 14 Mar 2010)

Log Message:
-----------
Fix #20486: blender hangs upon import attempt of an .obj with >40k polys.
Added automatic generation of lookup_int callbacks for collections, for
quicker lookup by index instead of looping over the whole thing. Import
is still quite slow, though now it only takes a few seconds.

The next bottleneck seems to be running update (depsgraph, notifiers, ..)
on setting every property. I fixed part of that by avoiding a notifier
to be added each time, now it checks for duplicates.

Modified Paths:
--------------
    trunk/blender/source/blender/makesrna/intern/makesrna.c
    trunk/blender/source/blender/makesrna/intern/rna_access.c
    trunk/blender/source/blender/makesrna/intern/rna_internal.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c

Modified: trunk/blender/source/blender/makesrna/intern/makesrna.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/makesrna.c     2010-03-14 
21:25:01 UTC (rev 27501)
+++ trunk/blender/source/blender/makesrna/intern/makesrna.c     2010-03-14 
22:30:57 UTC (rev 27502)
@@ -846,6 +846,98 @@
        return func;
 }
 
+static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, 
PropertyRNA *prop, PropertyDefRNA *dp, char *manualfunc, char *nextfunc)
+{
+       char *func;
+
+       if(prop->flag & PROP_IDPROPERTY)
+               return NULL;
+
+       if(!manualfunc) {
+               if(!dp->dnastructname || !dp->dnaname)
+                       return NULL;
+
+               /* only supported in case of standard next functions */
+               if(strcmp(nextfunc, "rna_iterator_array_next") == 0);
+               else if(strcmp(nextfunc, "rna_iterator_listbase_next") == 0);
+               else return NULL;
+       }
+
+       func= rna_alloc_function_name(srna->identifier, prop->identifier, 
"lookup_int");
+
+       fprintf(f, "PointerRNA %s(PointerRNA *ptr, int index)\n", func);
+       fprintf(f, "{\n");
+
+       if(manualfunc) {
+               fprintf(f, "\n  return %s(ptr, index);\n", manualfunc);
+               fprintf(f, "}\n\n");
+               return func;
+       }
+
+       fprintf(f, "    PointerRNA r_ptr;\n");
+       fprintf(f, "    CollectionPropertyIterator iter;\n\n");
+
+       fprintf(f, "    %s_%s_begin(&iter, ptr);\n\n", srna->identifier, 
prop->identifier);
+       fprintf(f, "    {\n");
+
+       if(strcmp(nextfunc, "rna_iterator_array_next") == 0) {
+               fprintf(f, "            ArrayIterator *internal= 
iter.internal;\n");
+               fprintf(f, "            if(internal->skip) {\n");
+               fprintf(f, "                    while(index-- > 0) {\n");
+               fprintf(f, "                            do {\n");
+               fprintf(f, "                                    internal->ptr 
+= internal->itemsize;\n");
+               fprintf(f, "                            } 
while(internal->skip(&iter, internal->ptr));\n");
+               fprintf(f, "                    }\n");
+               fprintf(f, "            }\n");
+               fprintf(f, "            else {\n");
+               fprintf(f, "                    internal->ptr += 
internal->itemsize*index;\n");
+               fprintf(f, "            }\n");
+       }
+       else if(strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {
+               fprintf(f, "            ListBaseIterator *internal= 
iter.internal;\n");
+               fprintf(f, "            if(internal->skip) {\n");
+               fprintf(f, "                    while(index-- > 0) {\n");
+               fprintf(f, "                            do {\n");
+               fprintf(f, "                                    internal->link= 
internal->link->next;\n");
+               fprintf(f, "                            } 
while(internal->skip(&iter, internal->link));\n");
+               fprintf(f, "                    }\n");
+               fprintf(f, "            }\n");
+               fprintf(f, "            else {\n");
+               fprintf(f, "                    while(index-- > 0)\n");
+               fprintf(f, "                            internal->link= 
internal->link->next;\n");
+               fprintf(f, "            }\n");
+       }
+
+       fprintf(f, "    }\n\n");
+
+       fprintf(f, "    r_ptr = %s_%s_get(&iter);\n", srna->identifier, 
prop->identifier);
+       fprintf(f, "    %s_%s_end(&iter);\n\n", srna->identifier, 
prop->identifier);
+
+       fprintf(f, "    return r_ptr;\n");
+
+#if 0
+       rna_print_data_get(f, dp);
+       item_type= (cprop->item_type)? (char*)cprop->item_type: "UnknownType";
+
+       if(dp->dnalengthname || dp->dnalengthfixed) {
+               if(dp->dnalengthname)
+                       fprintf(f, "\n  rna_array_lookup_int(ptr, &RNA_%s, 
data->%s, sizeof(data->%s[0]), data->%s, index);\n", item_type, dp->dnaname, 
dp->dnaname, dp->dnalengthname);
+               else
+                       fprintf(f, "\n  rna_array_lookup_int(ptr, &RNA_%s, 
data->%s, sizeof(data->%s[0]), %d, index);\n", item_type, dp->dnaname, 
dp->dnaname, dp->dnalengthfixed);
+       }
+       else {
+               if(dp->dnapointerlevel == 0)
+                       fprintf(f, "\n  return rna_listbase_lookup_int(ptr, 
&RNA_%s, &data->%s, index);\n", item_type, dp->dnaname);
+               else
+                       fprintf(f, "\n  return rna_listbase_lookup_int(ptr, 
&RNA_%s, data->%s, index);\n", item_type, dp->dnaname);
+       }
+#endif
+
+       fprintf(f, "}\n\n");
+
+       return func;
+}
+
 static char *rna_def_property_next_func(FILE *f, StructRNA *srna, PropertyRNA 
*prop, PropertyDefRNA *dp, char *manualfunc)
 {
        char *func, *getfunc;
@@ -1015,6 +1107,7 @@
                }
                case PROP_COLLECTION: {
                        CollectionPropertyRNA *cprop= 
(CollectionPropertyRNA*)prop;
+                       char *nextfunc= (char*)cprop->next;
 
                        if(dp->dnatype && strcmp(dp->dnatype, "ListBase")==0);
                        else if(dp->dnalengthname || dp->dnalengthfixed)
@@ -1031,6 +1124,7 @@
                        cprop->begin= (void*)rna_def_property_begin_func(f, 
srna, prop, dp, (char*)cprop->begin);
                        cprop->next= (void*)rna_def_property_next_func(f, srna, 
prop, dp, (char*)cprop->next);
                        cprop->end= (void*)rna_def_property_end_func(f, srna, 
prop, dp, (char*)cprop->end);
+                       cprop->lookupint= 
(void*)rna_def_property_lookup_int_func(f, srna, prop, dp, 
(char*)cprop->lookupint, nextfunc);
 
                        if(!(prop->flag & PROP_IDPROPERTY)) {
                                if(!cprop->begin) {

Modified: trunk/blender/source/blender/makesrna/intern/rna_access.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_access.c   2010-03-14 
21:25:01 UTC (rev 27501)
+++ trunk/blender/source/blender/makesrna/intern/rna_access.c   2010-03-14 
22:30:57 UTC (rev 27502)
@@ -2736,6 +2736,12 @@
        iter->internal= NULL;
 }
 
+PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct 
ListBase *lb, int index)
+{
+       void *data= BLI_findlink(lb, index);
+       return rna_pointer_inherit_refine(ptr, type, data);
+}
+
 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int 
itemsize, int length, int free_ptr, IteratorSkipFunc skip)
 {
        ArrayIterator *internal;
@@ -2800,6 +2806,14 @@
        iter->internal= NULL;
 }
 
+PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, 
int itemsize, int length, int index)
+{
+       if(index < 0 || index >= length)
+               return PointerRNA_NULL;
+
+       return rna_pointer_inherit_refine(ptr, type, ((char*)data) + 
index*itemsize);
+}
+
 /* RNA Path - Experiment */
 
 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, 
int bracket)

Modified: trunk/blender/source/blender/makesrna/intern/rna_internal.h
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_internal.h 2010-03-14 
21:25:01 UTC (rev 27501)
+++ trunk/blender/source/blender/makesrna/intern/rna_internal.h 2010-03-14 
22:30:57 UTC (rev 27502)
@@ -297,6 +297,7 @@
 void rna_iterator_listbase_next(struct CollectionPropertyIterator *iter);
 void *rna_iterator_listbase_get(struct CollectionPropertyIterator *iter);
 void rna_iterator_listbase_end(struct CollectionPropertyIterator *iter);
+PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct 
ListBase *lb, int index);
 
 typedef struct ArrayIterator {
        char *ptr;
@@ -311,6 +312,7 @@
 void *rna_iterator_array_get(struct CollectionPropertyIterator *iter);
 void *rna_iterator_array_dereference_get(struct CollectionPropertyIterator 
*iter);
 void rna_iterator_array_end(struct CollectionPropertyIterator *iter);
+PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, 
int itemsize, int length, int index);
 
 /* Duplicated code since we can't link in blenlib */
 

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c 
2010-03-14 21:25:01 UTC (rev 27501)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c 
2010-03-14 22:30:57 UTC (rev 27502)
@@ -108,6 +108,17 @@
 
 /* ********************* notifiers, listeners *************** */
 
+static int wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, 
void *reference)
+{
+       wmNotifier *note;
+
+       for(note=wm->queue.first; note; note=note->next)
+               if((note->category|note->data|note->subtype|note->action) == 
type && note->reference == reference)
+                       return 1;
+       
+       return 0;
+}
+
 /* XXX: in future, which notifiers to send to other windows? */
 void WM_event_add_notifier(const bContext *C, unsigned int type, void 
*reference)
 {
@@ -134,7 +145,7 @@
        Main *bmain= G.main;
        wmWindowManager *wm= bmain->wm.first;
 
-       if(wm) {
+       if(wm && !wm_test_duplicate_notifier(wm, type, reference)) {
                wmNotifier *note= MEM_callocN(sizeof(wmNotifier), "notifier");
                
                note->wm= wm;


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to