Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1424 - trunk/Model/Groups


Chronological Thread 
  • From: thiago@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1424 - trunk/Model/Groups
  • Date: Tue, 26 Jun 2007 15:35:41 -0600 (MDT)

Author: thiago
Date: Tue Jun 26 15:35:39 2007
New Revision: 1424

Modified:
   trunk/Model/Groups/Group.cc
   trunk/Model/Groups/Group.h
Log:
Group.cc, Group.h: Calling computeBounds will now check to see if the
bounds have already been computed, and if so, use that. If the objects
in the group are modified in a way not detected by the group, then
setDirty() should be called before computeBounds. 

I also added a parallel computeBounds method which should probably
always be used with groups if the group contains lots of objects.
This however only *computes* the bounds; it does not return it back.
Call the normal computeBounds after the parallel version in order to
get back the result. If someone would like to rename the parallel
version to something better than I have, please do so!

Modified: trunk/Model/Groups/Group.cc
==============================================================================
--- trunk/Model/Groups/Group.cc (original)
+++ trunk/Model/Groups/Group.cc Tue Jun 26 15:35:39 2007
@@ -1,4 +1,5 @@
 
+#include <Interface/Context.h>
 #include <Model/Groups/Group.h>
 #include <SCIRun/Core/Util/Assert.h>
 #include <algorithm>
@@ -11,11 +12,12 @@
   return new Group(args);
 }
 
-Group::Group(const vector<string>& /* args */)
+Group::Group(const vector<string>& /* args */): dirtybbox(true),
+       barrier("group barrier"), mutex("group mutex")
 {
 }
 
-Group::Group()
+Group::Group(): dirtybbox(true), barrier("group barrier"), mutex("group 
mutex")
 {
 }
 
@@ -31,11 +33,17 @@
   else
     copy = new Group();
 
+  //since we need to make clones of the things contained in the group,
+  //we can't just do copy->objs = objs;
   for(vector<Object*>::iterator iter = objs.begin();
       iter != objs.end(); ++iter) {
     Object *obj = *iter;
-    copy->add(static_cast<Object*>(obj->clone(depth)));
+    copy->objs.push_back(static_cast<Object*>(obj->clone(depth)));
   }
+  
+  copy->bbox = bbox;
+  copy->dirtybbox = dirtybbox;
+
   return copy;
 }
 
@@ -49,6 +57,9 @@
 Group::parallelInterpolate(const std::vector<keyframe_t> &group_keyframes,
                            int proc, int numProc)
 {
+  if (proc == 0)
+    setDirty();
+
   InterpErr worstError = success;
   vector<keyframe_t> keyframes(group_keyframes);
   
@@ -83,17 +94,23 @@
     if (retcode != success)
       worstError = retcode;
   }
+
+  //XXXX: should we have a barrier here to make sure everything is
+  //fully interpolated before other things get access to new data?
+
   return worstError;
 }
 
 void Group::add(Object* obj)
 {
   objs.push_back(obj);
+  dirtybbox = true;
 }
 
 void Group::set(int i, Object *obj) {
   ASSERT( i < objs.size() );
   objs[i] = obj;
+  dirtybbox = true;
 }
 
 Object *Group::get( int i ) {
@@ -106,12 +123,22 @@
     return objs[i];
 }
 
+bool Group::isDirty() const{
+  return dirtybbox;
+}
+
+void Group::setDirty()
+{
+  dirtybbox = true;
+}
+
 void Group::shrinkTo(int firstNumObjs, bool deleteRemainder)
 {
     if (deleteRemainder)
         for(int i=firstNumObjs;i<static_cast<int>(objs.size());i++)
             delete objs[i];
     objs.resize(firstNumObjs);
+    dirtybbox = true;
 }
 
 int Group::getSize() const
@@ -133,14 +160,56 @@
   for(vector<Object*>::iterator iter = objs.begin();
       iter != objs.end(); ++iter)
     (*iter)->preprocess(context);
+  dirtybbox = true;
 }
 
 void Group::computeBounds(const PreprocessContext& context, BBox& bbox) const
 {
-  for(vector<Object*>::const_iterator iter = objs.begin();
-      iter != objs.end(); ++iter)
-    (*iter)->computeBounds(context, bbox);
+  if (dirtybbox) {
+    for(vector<Object*>::const_iterator iter = objs.begin();
+        iter != objs.end(); ++iter)
+      (*iter)->computeBounds(context, bbox);
+    dirtybbox = false;
+  }
+  else {
+    bbox.extendByBox(this->bbox);
+  }
 }
+
+void Group::computeBounds(const PreprocessContext& context,
+                          int proc, int numProcs)
+{
+  BBox myBBox;
+  PreprocessContext dummyContext;
+
+  if (proc == 0) {
+    this->bbox.reset();
+  }
+
+  //Compute Bounding boxes in parallel
+  int size = getSize();
+  int start = proc*size/numProcs;
+  int end = (proc+1)*size/numProcs;
+  for (int i=start; i < end; ++i) {
+    objs[i]->computeBounds(dummyContext, myBBox);
+  }
+
+  //this barrier enforces that bbox has been initialized before
+  //threads start writing to it.
+  barrier.wait(numProcs);
+  
+  mutex.lock();
+  this->bbox.extendByBox(myBBox);
+  mutex.unlock();
+
+  if (proc == 0) {
+    dirtybbox = false;
+  }
+
+  //Need to wait for other threads to finish computing bbox
+  barrier.wait(numProcs);
+}
+
 
 void Group::intersect(const RenderContext& context, RayPacket& rays) const
 {

Modified: trunk/Model/Groups/Group.h
==============================================================================
--- trunk/Model/Groups/Group.h  (original)
+++ trunk/Model/Groups/Group.h  Tue Jun 26 15:35:39 2007
@@ -32,6 +32,9 @@
 
 
 #include <Interface/Object.h>
+#include <Core/Thread/Barrier.h>
+#include <SCIRun/Core/Thread/Mutex.h>
+#include <Core/Geometry/BBox.h>
 #include <sgi_stl_warnings_off.h>
 #include <vector>
 #include <string>
@@ -59,6 +62,11 @@
     Object *get( int i );
     const Object* get(int i) const;
     
+    //whether the group has been modified (is dirty) and needs state,
+    //such as the bounding box, to be updated.
+    bool isDirty() const;
+    void setDirty();
+
     vector<Object*> &getObjects() { return objs; }
     const vector<Object*> &getObjects() const { return objs; }
 
@@ -67,14 +75,24 @@
 
     virtual void preprocess(const PreprocessContext&);
     virtual void intersect(const RenderContext& context, RayPacket& rays) 
const;
+
+    //if the objects contained by the Group are modified, then
+    //setDirty() should be called before calling computeBounds so a
+    //new bound is calculated.
     virtual void computeBounds(const PreprocessContext& context,
                                BBox& bbox) const;
+    virtual void computeBounds(const PreprocessContext& context,
+                               int proc, int numProcs);
 
     static Group* create(const vector<string>& args);
 
   protected:
     vector<Object*> objs;
     vector<Object*>::iterator  parallelSplit; //point to the start of the 
parallel objects
+    BBox bbox;
+    mutable bool dirtybbox;
+    SCIRun::Barrier barrier;
+    SCIRun::Mutex mutex;
   };
 }
 




  • [MANTA] r1424 - trunk/Model/Groups, thiago, 06/26/2007

Archive powered by MHonArc 2.6.16.

Top of page