[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40917] branches/soc-2008-mxcurioni: Stability improvements for the Face Smoothness option.

Tamito Kajiyama rd6t-kjym at asahi-net.or.jp
Mon Oct 10 21:57:07 CEST 2011


Revision: 40917
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40917
Author:   kjym3
Date:     2011-10-10 19:57:06 +0000 (Mon, 10 Oct 2011)
Log Message:
-----------
Stability improvements for the Face Smoothness option.

The instability considered here is due to a persistent failure of the
getFEdge() method in the Interface0D class and its subclasses in the
presence of smooth FEdges.  When the Face Smoothness option is
enabled, the view map is populated with not only sharp FEdges (i.e.,
edges in the original meshes) but also smooth FEdges (i.e., newly
built edges lying on triangular surfaces).  The failure of getFEdge()
caused many related issues because the method is widely used in other
predicates and functions that rely on it.  The most prominent example
of related user-visible problems is a constant failure of the built-in
MaterialF0D.

The main issue and related problems were addressed as follows:

* A bug in the construction of smooth FEdges was fixed.  Individual
smooth FEdges, even when they were detected as a series of smooth
FEdges that constitute one smooth ViewEdge, may have some irregular
geometry in the form of non-uniform OWXFaceLayer::order values.  The
OWXFaceLayer::order values were used in an inappropriate way, so that
resulting smooth ViewEdges may have an FEdge between two subsequent
SVertices that were indeed the same SVertex object.  This was an
unexpected situation that getFEdge() could not handle.

* Another issue in the construction of smooth FEdges was resolved.
When sharp FEdges are constructed, two SVertices at both ends of an
FEdge are generated only when no SVertex exists in a given 3D position
(this way, the original mesh topology is reconstructed from a bunch of
independent triangles that the BlenderFileLoader class passes to the
view map creation process).  This sharing of SVertices was used also
for the generation of SVertices at the two ends of each smooth FEdge,
causing the getFEdge() failure in the presence of smooth FEdges.  The
workaround implemented here is to simply suppress the sharing of
generated SVertices when smooth FEdges are created.

* In the Parameter Editor mode, the built-in MaterialF0D was replaced
with a better implementation that works well with Curves and Strokes.
MaterialF0D does not work with these 1D data types.

Modified Paths:
--------------
    branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/Functions0D.py
    branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h

Modified: branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/Functions0D.py
===================================================================
--- branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/Functions0D.py	2011-10-10 18:19:54 UTC (rev 40916)
+++ branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/Functions0D.py	2011-10-10 19:57:06 UTC (rev 40917)
@@ -1,5 +1,16 @@
 from freestyle_init import *
 
+class CurveMaterialF0D(UnaryFunction0DMaterial):
+	# A replacement of the built-in MaterialF0D for stroke creation.
+	# MaterialF0D does not work with Curves and Strokes.
+	def getName(self):
+		return "CurveMaterialF0D"
+	def __call__(self, inter):
+		cp = inter.getObject()
+		assert(isinstance(cp, CurvePoint))
+		fe = cp.A().getFEdge(cp.B())
+		assert(fe is not None)
+		return fe.material() if fe.isSmooth() else fe.bMaterial()
 
 class pyInverseCurvature2DAngleF0D(UnaryFunction0DDouble):
 	def getName(self):

Modified: branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py
===================================================================
--- branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py	2011-10-10 18:19:54 UTC (rev 40916)
+++ branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py	2011-10-10 19:57:06 UTC (rev 40917)
@@ -287,7 +287,7 @@
 # Material modifiers
 
 def iter_material_color(stroke, material_attr):
-    func = MaterialF0D()
+    func = CurveMaterialF0D()
     it = stroke.strokeVerticesBegin()
     while not it.isEnd():
         material = func(it.castToInterface0DIterator())
@@ -305,7 +305,7 @@
         it.increment()
 
 def iter_material_value(stroke, material_attr):
-    func = MaterialF0D()
+    func = CurveMaterialF0D()
     it = stroke.strokeVerticesBegin()
     while not it.isEnd():
         material = func(it.castToInterface0DIterator())

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp	2011-10-10 18:19:54 UTC (rev 40916)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp	2011-10-10 19:57:06 UTC (rev 40917)
@@ -408,64 +408,71 @@
 }
 
 FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl){
+  WOEdge *woea, *woeb;
+  real ta, tb;
   SVertex *va, *vb;
   FEdgeSmooth *fe;
   // retrieve exact silhouette data
   WXSmoothEdge *se = ifl.fl->getSmoothEdge();
 
+  if (ifl.order) {
+    woea = se->woea();
+    woeb = se->woeb();
+	ta = se->ta();
+	tb = se->tb();
+  } else {
+    woea = se->woeb();
+    woeb = se->woea();
+	ta = se->tb();
+	tb = se->ta();
+  }
+
   Vec3r normal;
   // Make the 2 Svertices
   if(feprevious == 0){ // that means that we don't have any vertex already built for that face
-    real ta = se->ta();
-    Vec3r A1(se->woea()->GetaVertex()->GetVertex());
-    Vec3r A2(se->woea()->GetbVertex()->GetVertex());
+    Vec3r A1(woea->GetaVertex()->GetVertex());
+    Vec3r A2(woea->GetbVertex()->GetVertex());
     Vec3r A(A1+ta*(A2-A1));
     
-    va = MakeSVertex(A);
+    va = MakeSVertex(A, false);
     // Set normal:
-    Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(se->woea()->GetaVertex()));
-    Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(se->woea()->GetbVertex()));
+    Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(woea->GetaVertex()));
+    Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(woea->GetbVertex()));
     Vec3r na((1 - ta) * NA1 + ta * NA2);
     na.normalize();
     va->AddNormal(na);
     normal = na;
 
     // Set CurvatureInfo
-    CurvatureInfo* curvature_info_a = new CurvatureInfo(*(dynamic_cast<WXVertex*>(se->woea()->GetaVertex())->curvatures()),
-							*(dynamic_cast<WXVertex*>(se->woea()->GetbVertex())->curvatures()),
-							ta);
+    CurvatureInfo* curvature_info_a = new CurvatureInfo(
+		*(dynamic_cast<WXVertex*>(woea->GetaVertex())->curvatures()),
+		*(dynamic_cast<WXVertex*>(woea->GetbVertex())->curvatures()),
+		ta);
     va->setCurvatureInfo(curvature_info_a);
   }
   else
     va = feprevious->vertexB();
 
-  real tb = se->tb();
-  Vec3r B1(se->woeb()->GetaVertex()->GetVertex());
-  Vec3r B2(se->woeb()->GetbVertex()->GetVertex());
+  Vec3r B1(woeb->GetaVertex()->GetVertex());
+  Vec3r B2(woeb->GetbVertex()->GetVertex());
   Vec3r B(B1+tb*(B2-B1));
 
-  vb = MakeSVertex(B);
+  vb = MakeSVertex(B, false);
   // Set normal:
-  Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(se->woeb()->GetaVertex()));
-  Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(se->woeb()->GetbVertex()));
+  Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(woeb->GetaVertex()));
+  Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(woeb->GetbVertex()));
   Vec3r nb((1 - tb) * NB1 + tb * NB2);
   nb.normalize();
   normal += nb;
   vb->AddNormal(nb);
 
   // Set CurvatureInfo
-  CurvatureInfo* curvature_info_b = new CurvatureInfo(*(dynamic_cast<WXVertex*>(se->woeb()->GetaVertex())->curvatures()),
-						      *(dynamic_cast<WXVertex*>(se->woeb()->GetbVertex())->curvatures()),
-						      tb);
+  CurvatureInfo* curvature_info_b = new CurvatureInfo(
+	  *(dynamic_cast<WXVertex*>(woeb->GetaVertex())->curvatures()),
+	  *(dynamic_cast<WXVertex*>(woeb->GetbVertex())->curvatures()),
+	  tb);
   vb->setCurvatureInfo(curvature_info_b);
 
-  // if the order is false we must swap va and vb
-  if(!ifl.order){
-    SVertex *tmp = va;
-    va = vb;
-    vb = tmp;
-  }
-  
   // Creates the corresponding feature edge
   fe = new FEdgeSmooth(va, vb);
   fe->setNature(ifl.fl->nature());
@@ -580,8 +587,8 @@
     wxVB = (WXVertex*)iwe.e->GetaVertex();
   }
   // Make the 2 SVertex
-  va = MakeSVertex(wxVA->GetVertex());
-  vb = MakeSVertex(wxVB->GetVertex());
+  va = MakeSVertex(wxVA->GetVertex(), true);
+  vb = MakeSVertex(wxVB->GetVertex(), true);
 
   // get the faces normals and the material indices
   Vec3r normalA, normalB;
@@ -643,21 +650,28 @@
 }
 
 SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){
+  SVertex *va = new SVertex(iPoint, _currentSVertexId);
+  SilhouetteGeomEngine::ProjectSilhouette(va);
+  ++_currentSVertexId;
+  // Add the svertex to the SShape svertex list:
+  _pCurrentSShape->AddNewVertex(va);
+  return va;
+}
+
+SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint, bool shared){
   SVertex *va;
-  // Check whether the vertices are already in the table:
-  // fisrt vertex
-  // -------------
-  SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
-  if (found != _SVertexMap.end()) {
-    va = (*found).second;
-  }else{
-    va = new SVertex(iPoint, _currentSVertexId);
-    SilhouetteGeomEngine::ProjectSilhouette(va);
-    ++_currentSVertexId;
-    // Add the svertex to the SShape svertex list:
-    _pCurrentSShape->AddNewVertex(va);
-    // Add the svertex in the table using its id:
-    _SVertexMap[iPoint] = va; 
+  if (!shared) {
+	va = MakeSVertex(iPoint);
+  } else {
+	// Check whether the iPoint is already in the table
+	SVertexMap::const_iterator found = _SVertexMap.find(iPoint);
+	if (shared && found != _SVertexMap.end()) {
+	  va = (*found).second;
+	}else{
+	  va = MakeSVertex(iPoint);
+	  // Add the svertex into the table using iPoint as the key
+	  _SVertexMap[iPoint] = va; 
+	}
   }
   return va;
 }

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h	2011-10-10 18:19:54 UTC (rev 40916)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h	2011-10-10 19:57:06 UTC (rev 40917)
@@ -198,8 +198,10 @@
   FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe);
 
   // GENERAL //
+  /*! Instanciate a SVertex */
+  SVertex * MakeSVertex(Vec3r& iPoint);
   /*! Instanciate a SVertex if it hasn't been already created */
-  SVertex * MakeSVertex(Vec3r& iPoint);
+  SVertex * MakeSVertex(Vec3r& iPoint, bool shared);
   /*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */
   ViewVertex * MakeViewVertex(SVertex *iSVertex);
 




More information about the Bf-blender-cvs mailing list