[suggestion] generate many objects all at once


(guang liang chen) #1

hi
I’m writing an addon call “green_land” which will generate many objects all at once(more than 10000) but now the bpy api only can generate one object at a time,so It’s very slow to generate 10000 objects using the for i in range(10000): way to do that. can we have an api that can generates many objects all at once?


(RickyBlender) #2

happy bl


(guang liang chen) #3

@RickyBlender
thank you for the link,but I do using the copy object and link them to the scene,but still, copy more than 10000 empty object take about 20s it is way too slow compare to the particles generating instance objects speed maybe 100time slower


(RickyBlender) #4

might be normal for 10 000
anything higher then 1000 makes blender sluggish !

happy bl


(guang liang chen) #5

I now try to using ctypes module in python to generate more than 10000 copy objects ,it works and within one second.but I have one trouble that after generation,if I open another scene ,it crash ,I can’t figure out why.
here is the file written as an addon:
TEST_generate_objects via ctypes.zip (137 KB)
https://s5.postimg.org/sk02tjog7/test_object.gif

here is the c++ code which will be compiled as “test_generate_objects64.dll” file for loading in py



#define WIN32
#define __cplusplus
#define EXC  extern "C" __declspec(dllexport)
//----set your blender Environment to include the Underneath path--------------------------
#include<stdio.h>
#include <malloc.h>
#include<string.h>//memcpy

#include<DNA_ID.h>

#include<DNA_object_types.h>

#include<DNA_scene_types.h>
#include<DNA_listBase.h>

typedef struct bContext {
    int thread;

    /*windowmanager context*/
    struct {
        struct wmWindowManager*manager;
        struct wmWindow*window;
        struct bScreen*screen;
        struct ScrArea*area;
        struct ARegion*region;
        struct ARegion*menu;
        struct bContextStore*store;
        const char*operator_poll_msg; /*reason for poll failing*/
    } wm;
    
    /*data context*/
    struct {
        struct Main*main;
        struct Scene*scene;

        int recursion;
        int py_init; /*true if python is initialized*/
        void*py_context;
    } data;
}bContext;
    
////////////////////////////////////////////
void BLI_addhead(ListBase *listbase, void *vlink)
    {
    Link *link =(Link*) vlink;

    if (link == NULL) return;

    link->next =(Link*) listbase->first;
    link->prev = NULL;

    if (listbase->first) ((Link *)listbase->first)->prev = link;
    if (listbase->last == NULL) listbase->last = link;
    listbase->first = link;
    }

Base *BKE_scene_base_add(Scene *sce, Object *ob)
    {
    Base*base = (Base*)malloc(sizeof(*base));
    BLI_addhead(&sce->base, base);
    base->object = ob;
    base->flag = ob->flag;
    base->lay = ob->lay;

    return base;
    }




void linkO(const bContext*C,Object*o)//O
    {
    Scene*scene=C->data.scene;//PRINT1(,O->id.name,s);

    BKE_scene_base_add(scene,o);


    }




////copy//////////////////////////////////////
EXC void copy_objects(bContext*C,Object*o,int iNum)//export to py
    {
    Scene*scene=C->data.scene;
    //Object*o新=(Object*)MEM_callocN(sizeof(Object), "object");
    for(int i=0;i<iNum;i++)
        {
        Object*oCopy=(Object*)malloc(sizeof(Object));
        memcpy(oCopy,o,sizeof(Object));

        linkO(C,oCopy);
        }
    }

    


(guang liang chen) #6

I have solved this speed problem ,I using cytpes to copy the object .now It can generate 20000 objects within one second.
here is the addon to generate 20000 objects,there are two buttons (generate use C++ / generate use py) to compare the speed
TEST_generate_objects(20000within one sceond).zip (79.8 KB)
test_generate_objects(C++ source compile to dll).zip (2.35 KB)
here is the comparision of C++ and py speed:
C
https://s5.postimg.org/jhblmiop3/test_object_C.gif

py:
https://s5.postimg.org/y1x9v391j/test_object_py.gif


(RickyBlender) #7

nice find here

is there a thread that explains how this work ?

I see that it is using a C DLL to get it done
will have to test that with my own object and time it

very interesting

thanks for feedback

happy bl


(guang liang chen) #8

yes,I use C++ code to do that. I have attached the source file here .you can try to complile this cpp file to “test_generate_objects64.dll” as a module being call by python via ctypes.
test_generate_objects(C++ source compile to dll).zip (2.35 KB)


(RickyBlender) #9

you mean this has to be compile in C
darn I don’t have anything to do that and don’t really work with C

still a good reference for those who can work in C

thanks anyway
happy bl


(guang liang chen) #10

so,I still think that we should have a python api to do the same job,the C code is not friendly for every one.and this C code still have something wrong.


(RickyBlender) #11

we are supposed to get more in 2.8
but have to wait till we see what we get !

you could do a script using CUDA python
but not certain of speed increase !

happy bl