Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2009-10-04 20:56:00 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2009-10-04 20:56:00 +0400
commit55541d8a8143b97ce0d452caf4ececa8903c31a0 (patch)
treea381d591f2c9b7bd95bc5766ed4c498380e0b5c0 /source/blender/render/intern
parent8da55763b541075dae4b1f7713c43af2b609e332 (diff)
Added some test_break during the build process.
(Maybe later this should be done with some thread_cancel function instead of doing variable/callbacks tests)
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/include/rayobject.h24
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp7
-rw-r--r--source/blender/render/intern/raytrace/rayobject_qbvh.cpp12
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp5
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.h2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_svbvh.cpp20
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp9
-rw-r--r--source/blender/render/intern/raytrace/vbvh.h26
-rw-r--r--source/blender/render/intern/source/rayshade.c104
9 files changed, 158 insertions, 51 deletions
diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h
index 337f9ca3fdd..9e35c0feac5 100644
--- a/source/blender/render/intern/include/rayobject.h
+++ b/source/blender/render/intern/include/rayobject.h
@@ -93,6 +93,21 @@ extern "C" {
#define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3)
+
+/*
+ * This class is intended as a place holder for control, configuration of the rayobject like:
+ * - stop building (TODO maybe when porting build to threads this could be implemented with some thread_cancel function)
+ * - max number of threads and threads callback to use during build
+ * ...
+ */
+typedef int (*RE_rayobjectcontrol_test_break_callback)(void *data);
+typedef struct RayObjectControl RayObjectControl;
+struct RayObjectControl
+{
+ void *data;
+ RE_rayobjectcontrol_test_break_callback test_break;
+};
+
/*
* This rayobject represents a generic object. With it's own callbacks for raytrace operations.
* It's suitable to implement things like LOD.
@@ -100,9 +115,13 @@ extern "C" {
struct RayObject
{
struct RayObjectAPI *api;
+
+ struct RayObjectControl control;
};
+
+
typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject);
typedef void (*RE_rayobject_done_callback)(RayObject *);
@@ -144,6 +163,11 @@ int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as
float RE_rayobject_cost(RayObject *r);
+/*
+ * Returns true if for some reason a heavy processing function should stop
+ * (eg.: user asked to stop during a tree a build)
+ */
+int RE_rayobjectcontrol_test_break(RayObjectControl *c);
#define ISECT_EPSILON ((float)FLT_EPSILON)
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index 34faa2951ce..95387cf1ee4 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -528,3 +528,10 @@ void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
else assert(0);
}
+int RE_rayobjectcontrol_test_break(RayObjectControl *control)
+{
+ if(control->test_break)
+ return control->test_break( control->data );
+
+ return 0;
+}
diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
index 59daf9dc962..b18ee0824cf 100644
--- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
@@ -47,7 +47,7 @@ struct QBVHTree
template<>
void bvh_done<QBVHTree>(QBVHTree *obj)
{
- rtbuild_done(obj->builder);
+ rtbuild_done(obj->builder, &obj->rayobj.control);
//TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
@@ -59,7 +59,15 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
//Build and optimize the tree
//TODO do this in 1 pass (half memory usage during building)
- VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
+ VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder);
+
+ if(RE_rayobjectcontrol_test_break(&obj->rayobj.control))
+ {
+ BLI_memarena_free(arena1);
+ BLI_memarena_free(arena2);
+ return;
+ }
+
pushup_simd<VBVHNode,4>(root);
obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index 430045b56b6..9523e725893 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -130,11 +130,14 @@ static void object_sort(Item *begin, Item *end, int axis)
assert(false);
}
-void rtbuild_done(RTBuilder *b)
+void rtbuild_done(RTBuilder *b, RayObjectControl* ctrl)
{
for(int i=0; i<3; i++)
if(b->sorted_begin[i])
+ {
+ if(RE_rayobjectcontrol_test_break(ctrl)) break;
object_sort( b->sorted_begin[i], b->sorted_end[i], i );
+ }
}
RayObject* rtbuild_get_primitive(RTBuilder *b, int index)
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h
index 8f471f095e2..71665681586 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h
@@ -85,7 +85,7 @@ typedef struct RTBuilder
RTBuilder* rtbuild_create(int size);
void rtbuild_free(RTBuilder *b);
void rtbuild_add(RTBuilder *b, RayObject *o);
-void rtbuild_done(RTBuilder *b);
+void rtbuild_done(RTBuilder *b, RayObjectControl *c);
void rtbuild_merge_bb(RTBuilder *b, float *min, float *max);
int rtbuild_size(RTBuilder *b);
diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
index f806fcf93ef..229e82dfa68 100644
--- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
@@ -58,7 +58,7 @@ struct PackCost
template<>
void bvh_done<SVBVHTree>(SVBVHTree *obj)
{
- rtbuild_done(obj->builder);
+ rtbuild_done(obj->builder, &obj->rayobj.control);
//TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
@@ -71,7 +71,14 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
//Build and optimize the tree
if(0)
{
- VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
+ VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1,&obj->rayobj.control).transform(obj->builder);
+ if(RE_rayobjectcontrol_test_break(&obj->rayobj.control))
+ {
+ BLI_memarena_free(arena1);
+ BLI_memarena_free(arena2);
+ return;
+ }
+
reorganize(root);
remove_useless(root, &root);
bvh_refit(root);
@@ -86,7 +93,14 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
{
//Finds the optimal packing of this tree using a given cost model
//TODO this uses quite a lot of memory, find ways to reduce memory usage during building
- OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1).transform(obj->builder);
+ OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1,&obj->rayobj.control).transform(obj->builder);
+ if(RE_rayobjectcontrol_test_break(&obj->rayobj.control))
+ {
+ BLI_memarena_free(arena1);
+ BLI_memarena_free(arena2);
+ return;
+ }
+
VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root);
obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root);
}
diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
index 5260abf67ae..11f04c04141 100644
--- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
@@ -72,7 +72,7 @@ struct PackCost
template<>
void bvh_done<VBVHTree>(VBVHTree *obj)
{
- rtbuild_done(obj->builder);
+ rtbuild_done(obj->builder, &obj->rayobj.control);
//TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
@@ -81,7 +81,12 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
//Build and optimize the tree
if(1)
{
- VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
+ VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1,&obj->rayobj.control).transform(obj->builder);
+ if(RE_rayobjectcontrol_test_break(&obj->rayobj.control))
+ {
+ BLI_memarena_free(arena1);
+ return;
+ }
reorganize(root);
remove_useless(root, &root);
diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h
index db1df43f665..1ff51786e52 100644
--- a/source/blender/render/intern/raytrace/vbvh.h
+++ b/source/blender/render/intern/raytrace/vbvh.h
@@ -107,10 +107,18 @@ template<class Node>
struct BuildBinaryVBVH
{
MemArena *arena;
+ RayObjectControl *control;
- BuildBinaryVBVH(MemArena *a)
+ void test_break()
+ {
+ if(RE_rayobjectcontrol_test_break(control))
+ throw "Stop";
+ }
+
+ BuildBinaryVBVH(MemArena *a, RayObjectControl *c)
{
arena = a;
+ control = c;
}
Node *create_node()
@@ -131,6 +139,18 @@ struct BuildBinaryVBVH
Node *transform(RTBuilder *builder)
{
+ try
+ {
+ return _transform(builder);
+
+ } catch(...)
+ {
+ }
+ return NULL;
+ }
+
+ Node *_transform(RTBuilder *builder)
+ {
int size = rtbuild_size(builder);
if(size == 1)
@@ -143,6 +163,8 @@ struct BuildBinaryVBVH
}
else
{
+ test_break();
+
Node *node = create_node();
INIT_MINMAX(node->bb, node->bb+3);
@@ -157,7 +179,7 @@ struct BuildBinaryVBVH
RTBuilder tmp;
rtbuild_get_child(builder, i, &tmp);
- *child = transform(&tmp);
+ *child = _transform(&tmp);
child = &((*child)->sibling);
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 641085d8cd6..9ef8aa3aba2 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -72,8 +72,26 @@
/* only to be used here in this file, it's for speed */
extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-RayObject * RE_rayobject_create(int type, int size)
+static int test_break(void *data)
{
+ Render *re = (Render*)data;
+ return re->test_break(re->tbh);
+}
+
+static RE_rayobject_config_control(RayObject *r, Render *re)
+{
+ if(RE_rayobject_isRayAPI(r))
+ {
+ r = RE_rayobject_align( r );
+ r->control.data = re;
+ r->control.test_break = test_break;
+ }
+}
+
+RayObject* RE_rayobject_create(Render *re, int type, int size)
+{
+ RayObject * res = NULL;
+
if(type == R_RAYSTRUCTURE_AUTO)
{
//TODO
@@ -83,30 +101,21 @@ RayObject * RE_rayobject_create(int type, int size)
// type = R_RAYSTRUCTURE_VBVH;
}
- if(type == R_RAYSTRUCTURE_OCTREE)
- {
- //TODO dynamic ocres
- return RE_rayobject_octree_create(R.r.ocres, size);
- }
- if(type == R_RAYSTRUCTURE_BLIBVH)
- {
- return RE_rayobject_blibvh_create(size);
- }
- if(type == R_RAYSTRUCTURE_VBVH)
- {
- return RE_rayobject_vbvh_create(size);
- }
- if(type == R_RAYSTRUCTURE_SIMD_SVBVH)
- {
- return RE_rayobject_svbvh_create(size);
- }
- if(type == R_RAYSTRUCTURE_SIMD_QBVH)
- {
- return RE_rayobject_qbvh_create(size);
- }
- assert( NULL );
+ if(type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres
+ res = RE_rayobject_octree_create(re->r.ocres, size);
+ else if(type == R_RAYSTRUCTURE_BLIBVH)
+ res = RE_rayobject_blibvh_create(size);
+ else if(type == R_RAYSTRUCTURE_VBVH)
+ res = RE_rayobject_vbvh_create(size);
+ else if(type == R_RAYSTRUCTURE_SIMD_SVBVH)
+ res = RE_rayobject_svbvh_create(size);
+ else if(type == R_RAYSTRUCTURE_SIMD_QBVH)
+ res = RE_rayobject_qbvh_create(size);
+
+ if(res)
+ RE_rayobject_config_control( res, re );
- return NULL;
+ return res;
}
#ifdef RE_RAYCOUNTER
@@ -217,7 +226,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
assert( faces > 0 );
//Create Ray cast accelaration structure
- raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_structure, faces );
+ raytree = obr->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces );
if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
else
@@ -311,7 +320,7 @@ static void makeraytree_single(Render *re)
}
//Create raytree
- raytree = re->raytree = RE_rayobject_create( re->r.raytrace_structure, faces+special );
+ raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special );
if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
{
@@ -325,6 +334,9 @@ static void makeraytree_single(Render *re)
for(obi=re->instancetable.first; obi; obi=obi->next)
if(is_raytraceable(re, obi))
{
+ if(test_break(re))
+ break;
+
if(has_special_rayobject(re, obi))
{
RayObject *obj = makeraytree_object(re, obi);
@@ -371,10 +383,13 @@ static void makeraytree_single(Render *re)
}
}
- re->i.infostr= "Raytree.. building";
- re->stats_draw(re->sdh, &re->i);
+ if(!test_break(re))
+ {
+ re->i.infostr= "Raytree.. building";
+ re->stats_draw(re->sdh, &re->i);
- RE_rayobject_done( raytree );
+ RE_rayobject_done( raytree );
+ }
}
void makeraytree(Render *re)
@@ -391,20 +406,29 @@ void makeraytree(Render *re)
re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS);
BENCH(makeraytree_single(re), tree_build);
-
- //Calculate raytree max_size
- //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights
- RE_rayobject_merge_bb( re->raytree, min, max );
- for(i=0; i<3; i++)
+ if(test_break(re))
{
- min[i] += 0.01f;
- max[i] += 0.01f;
- sub[i] = max[i]-min[i];
+ freeraytree(re);
+
+ re->i.infostr= "Raytree building canceled";
+ re->stats_draw(re->sdh, &re->i);
}
- re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] );
+ else
+ {
+ //Calculate raytree max_size
+ //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights
+ RE_rayobject_merge_bb( re->raytree, min, max );
+ for(i=0; i<3; i++)
+ {
+ min[i] += 0.01f;
+ max[i] += 0.01f;
+ sub[i] = max[i]-min[i];
+ }
+ re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] );
- re->i.infostr= "Raytree finished";
- re->stats_draw(re->sdh, &re->i);
+ re->i.infostr= "Raytree finished";
+ re->stats_draw(re->sdh, &re->i);
+ }
}
void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)