A few attempts to reduce the amount of memory consumption in Freestyle.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Fri, 3 Dec 2010 23:17:49 +0000 (23:17 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Fri, 3 Dec 2010 23:17:49 +0000 (23:17 +0000)
* Made changes to the Controller so that dynamically allocated
memory areas (e.g. imported mesh data, winged edges, and a view map)
are released soon after they become unnecessary.

* Added a new feature edge selection criterion based on image border.

When the "Selection by Image Border" option is enabled, feature edges
are selected only if they are within the border of the image being
rendered.  The border is defined either by the frame size or a border
region (specified by the Shift-B key in a 3D View window).  When large
scenes are rendered, this clipping by the image border leads to less
memory consumption.

* Enabled the "Silhouette", "Border", and "Crease" edge types of
the Selection by Edge Types option by default.

When no edge types are specified, all feature edges including "Ridge",
"Valley" and "Suggestive Contour" are detected at the cost of extra
memory consumption.  Disabling these three edge types and enabling
some other edge type leads to less memory consumption.  This change
is intended to help new Freestyle users by providing a typical, low
memory consumption default setting.

* Slightly rearranged the UI controls for feature edge selection.

release/scripts/freestyle/style_modules/parameter_editor.py
release/scripts/ui/properties_render.py
source/blender/freestyle/intern/application/Controller.cpp
source/blender/freestyle/intern/application/Controller.h
source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
source/blender/makesdna/DNA_freestyle_types.h
source/blender/makesrna/intern/rna_scene.c

index 83c5bcaef805cc8055bf24c54bf290b92834d140..cf4a87d2ee52a89ffaa1c08187db592484d8de1c 100644 (file)
@@ -312,6 +312,22 @@ class ObjectNamesUP1D(UnaryPredicate1D):
             return not found
         return found
 
+class WithinImageBorderUP1D(UnaryPredicate1D):
+    def __init__(self, xmin, xmax, ymin, ymax):
+        UnaryPredicate1D.__init__(self)
+        self._xmin = xmin
+        self._xmax = xmax
+        self._ymin = ymin
+        self._ymax = ymax
+    def getName(self):
+        return "WithinImageBorderUP1D"
+    def __call__(self, inter):
+        return self.withinBorder(inter.A()) or self.withinBorder(inter.B())
+    def withinBorder(self, vert):
+        x = vert.getProjectedX()
+        y = vert.getProjectedY()
+        return self._xmin <= x <= self._xmax and self._ymin <= y <= self._ymax
+
 # Stroke caps
 
 def iter_stroke_vertices(stroke):
@@ -525,6 +541,20 @@ def process(layer_name, lineset_name):
             names = dict((ob.name, True) for ob in lineset.group.objects)
             upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE')
             selection_criteria.append(upred)
+    # prepare selection criteria by image border
+    if lineset.select_by_image_border:
+        w = scene.render.resolution_x
+        h = scene.render.resolution_y
+        if scene.render.use_border:
+            xmin = scene.render.border_min_x * w
+            xmax = scene.render.border_max_x * w
+            ymin = scene.render.border_min_y * h
+            ymax = scene.render.border_max_y * h
+        else:
+            xmin, xmax = 0.0, float(w)
+            ymin, ymax = 0.0, float(h)
+        upred = WithinImageBorderUP1D(xmin, xmax, ymin, ymax)
+        selection_criteria.append(upred)
     # do feature edge selection
     upred = join_unary_predicates(selection_criteria, AndUP1D)
     if upred is None:
index 1dd59aecc5a24f9a7ce4234e0cef59e0de3a3bfe..13b3a1586c6b813598bb173cdf536dd899e6fe7a 100644 (file)
@@ -257,6 +257,9 @@ class RENDER_PT_freestyle(RenderButtonsPanel, bpy.types.Panel):
                     col.prop(lineset, "group")
                     row = col.row()
                     row.prop(lineset, "group_negation", expand=True)
+                    col.separator() # XXX
+
+                col.prop(lineset, "select_by_image_border")
 
         else: # freestyle.mode == "SCRIPT"
 
index e26e001e5abbd7cdfb4bdacd4b72d0c0dfe7e794..bcb902817bf77bbcea848fa7b8d86d31cdbf8448 100755 (executable)
@@ -295,34 +295,68 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer* srl)
   cout << "Triangles nb     : " << _SceneNumFaces << endl;
   _bboxDiag = (_RootNode->bbox().getMax()-_RootNode->bbox().getMin()).norm();
   cout << "Bounding Box     : " << _bboxDiag << endl;
+
+  ClearRootNode();
+
   return 0;
 }
 
-
 void Controller::CloseFile()
 {
   WShape::setCurrentId(0);
-  _pView->DetachModel();
   _ListOfModels.clear();
-  if(NULL != _RootNode)
-    {
-      int ref = _RootNode->destroy();
-      if(0 == ref)
-       _RootNode->addRef();
-    
-      _RootNode->clearBBox();
-    }
-  
-  _pView->DetachSilhouette();
-  if (NULL != _SilhouetteNode)
-    {
-      int ref = _SilhouetteNode->destroy();
-      if(0 == ref)
+
+  // We deallocate the memory:
+  ClearRootNode();
+  DeleteWingedEdge();
+  DeleteViewMap();
+
+  // clears the canvas
+  _Canvas->Clear();
+
+  // soc: reset passes
+  setPassDiffuse(NULL, 0, 0);
+  setPassZ(NULL, 0, 0);
+}
+
+void Controller::ClearRootNode()
+{
+       _pView->DetachModel();
+       if(NULL != _RootNode)
        {
-         delete _SilhouetteNode;
-         _SilhouetteNode = NULL;
+               int ref = _RootNode->destroy();
+               if(0 == ref)
+                       _RootNode->addRef();
+               _RootNode->clearBBox();
        }
-    }
+}
+
+void Controller::DeleteWingedEdge()
+{
+       if(_winged_edge)
+       {
+               delete _winged_edge;
+               _winged_edge = NULL;
+       }
+
+       // clears the grid
+       _Grid.clear();
+       _SceneNumFaces = 0;
+       _minEdgeSize = DBL_MAX;
+}
+
+void Controller::DeleteViewMap()
+{
+       _pView->DetachSilhouette();
+       if (NULL != _SilhouetteNode)
+       {
+               int ref = _SilhouetteNode->destroy();
+               if(0 == ref) {
+                       delete _SilhouetteNode;
+                       _SilhouetteNode = NULL;
+               }
+       }
+
   //  if(NULL != _ProjectedSilhouette)
   //    {
   //      int ref = _ProjectedSilhouette->destroy();
@@ -340,43 +374,21 @@ void Controller::CloseFile()
   //     delete _VisibleProjectedSilhouette;
   //     _VisibleProjectedSilhouette = NULL;
   //   }
-  //  }
-  
-  _pView->DetachDebug();
-  if(NULL != _DebugNode)
-    {
+  //  }  
+
+       _pView->DetachDebug();
+       if(NULL != _DebugNode) {
       int ref = _DebugNode->destroy();
       if(0 == ref)
-       _DebugNode->addRef();
+                 _DebugNode->addRef();
     }
-  
-  if(_winged_edge) {
-    delete _winged_edge;
-    _winged_edge = NULL;
-  }
 
-  // We deallocate the memory:
-  if(NULL != _ViewMap)
-    {
+       if(NULL != _ViewMap) {
       delete _ViewMap;
       _ViewMap = 0;
     }
-
-  // clears the canvas
-  _Canvas->Clear();
-
-  // clears the grid
-  _Grid.clear();
-  _SceneNumFaces = 0;
-  _minEdgeSize = DBL_MAX;
-
-  // soc: reset passes
-  setPassDiffuse(NULL, 0, 0);
-  setPassZ(NULL, 0, 0);
 }
 
-
-
 void Controller::ComputeViewMap()
 {
 
@@ -527,6 +539,8 @@ void Controller::ComputeViewMap()
   }
   // Reset Style modules modification flags
   resetModified(true);
+
+  DeleteWingedEdge();
 }
 
 void Controller::ComputeSteerableViewMap(){
@@ -699,6 +713,7 @@ void Controller::ResetRenderCount()
 Render* Controller::RenderStrokes(Render *re) {
        BlenderStrokeRenderer* blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count);
        _Canvas->Render( blenderRenderer );
+       DeleteViewMap();
        Render* freestyle_render = blenderRenderer->RenderScene(re);
        delete blenderRenderer;
        
index dfff7d7079c8a75a2398ce6d83f3e45f299fdce0..a278b10a090984ad787972bf4319ff995e15647e 100755 (executable)
@@ -94,6 +94,9 @@ public:
   void RemoveStyleModule(unsigned index);
   void ReloadStyleModule(unsigned index, const char * iFileName);
   void Clear();
+  void ClearRootNode();
+  void DeleteWingedEdge();
+  void DeleteViewMap();
   void toggleLayer(unsigned index, bool iDisplay);
   void setModified(unsigned index, bool iMod);
   void resetModified(bool iMod=false);
@@ -106,10 +109,10 @@ public:
   NodeGroup* BuildRep(vector<ViewEdge*>::iterator vedges_begin, 
                      vector<ViewEdge*>::iterator vedges_end) ;
   
-  NodeGroup* debugNode() {return _DebugNode;}
-  AppView * view() {return _pView;}
-  NodeGroup* debugScene() {return _DebugNode;}
-  Grid& grid() {return _Grid;}
+  //NodeGroup* debugNode() {return _DebugNode;}
+  //AppView * view() {return _pView;}
+  //NodeGroup* debugScene() {return _DebugNode;}
+  //Grid& grid() {return _Grid;}
   
   void toggleVisibilityAlgo();
 
index e17a66e636412f5697bd0f9957ae23267c33f698..5c6fc04757230c63715bfd6f97d2bee8188599c7 100644 (file)
@@ -439,11 +439,11 @@ extern "C" {
 
                lineset->linestyle = FRS_new_linestyle("LineStyle", NULL);
                lineset->flags |= FREESTYLE_LINESET_ENABLED;
-               lineset->selection = 0;
+               lineset->selection = FREESTYLE_SEL_IMAGE_BORDER;
                lineset->qi = FREESTYLE_QI_VISIBLE;
                lineset->qi_start = 0;
                lineset->qi_end = 100;
-               lineset->edge_types = 0;
+               lineset->edge_types = FREESTYLE_FE_SILHOUETTE | FREESTYLE_FE_BORDER | FREESTYLE_FE_CREASE;
                lineset->group = NULL;
                if (lineset_index > 0)
                        sprintf(lineset->name, "LineSet %i", lineset_index+1);
index 4b55a157ecafee2100a2a0462c37bee046fc5d35..390f726de574b2a13e783be86af6a15432adf069 100644 (file)
@@ -53,9 +53,10 @@ struct FreestyleLineStyle;
 #define FREESTYLE_LINESET_GR_NOT   16
 
 /* FreestyleLineSet::selection */
-#define FREESTYLE_SEL_VISIBILITY  1
-#define FREESTYLE_SEL_EDGE_TYPES  2
-#define FREESTYLE_SEL_GROUP       4
+#define FREESTYLE_SEL_VISIBILITY    1
+#define FREESTYLE_SEL_EDGE_TYPES    2
+#define FREESTYLE_SEL_GROUP         4
+#define FREESTYLE_SEL_IMAGE_BORDER  8
 
 /* FreestyleLineSet::fedge_types */
 #define FREESTYLE_FE_SILHOUETTE          1
index f720b0046723960feb1b598afd70f5f7065a8c2e..00adde7e6ca7c7332418d460b0254c6a9b828023 100644 (file)
@@ -1707,6 +1707,11 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Selection by Group", "Select feature edges based on a group of objects.");
        RNA_def_property_update(prop, NC_SCENE, NULL);
 
+       prop= RNA_def_property(srna, "select_by_image_border", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "selection", FREESTYLE_SEL_IMAGE_BORDER);
+       RNA_def_property_ui_text(prop, "Selection by Image Border", "Select feature edges by image border (less memory consumption).");
+       RNA_def_property_update(prop, NC_SCENE, NULL);
+
        prop= RNA_def_property(srna, "edge_type_negation", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
        RNA_def_property_enum_items(prop, edge_type_negation_items);