[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25864] branches/soc-2008-mxcurioni/source /blender/freestyle/intern: Fixed a bug in SilhouetteGeomEngine:: ImageToWorldParameter() that caused

Tamito Kajiyama rd6t-kjym at asahi-net.or.jp
Sun Jan 10 15:08:59 CET 2010


Revision: 25864
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25864
Author:   kjym3
Date:     2010-01-10 15:08:59 +0100 (Sun, 10 Jan 2010)

Log Message:
-----------
Fixed a bug in SilhouetteGeomEngine::ImageToWorldParameter() that caused
instability issues regarding the view map creation.  A new iterative
solver of the 2D-to-3D inverse projection transformation problem was
implemented.  Instead of directly solving the problem in the direction
from the 2D to 3D space, the new solver starts with an initial guess of
an approximated solution and asymptotically approaches to the true
solution by iteratively performing the forward 3D-to-2D projection
transformation and improving the approximation.  Preliminary tests with
one simple and another complex scenes showed that the solver converges
quickly (more and less 20 iterations in many cases, with a stopping
criterion of a residual distance between the true and approximated
solutions less than 1e-6 Blender Unit).

Modified Paths:
--------------
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
    branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp	2010-01-10 11:09:30 UTC (rev 25863)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp	2010-01-10 14:08:59 UTC (rev 25864)
@@ -21,9 +21,21 @@
 
 	cout << "\n===  Importing triangular meshes into Blender  ===" << endl;
 
-  // creation of the scene root node
-  _Scene = new NodeGroup;
+	// creation of the scene root node
+	_Scene = new NodeGroup;
 
+	_viewplane_left=   _re->viewplane.xmin;
+	_viewplane_right=  _re->viewplane.xmax;
+	_viewplane_bottom= _re->viewplane.ymin;
+	_viewplane_top=    _re->viewplane.ymax;
+	_z_near= _re->clipsta;
+	_z_far=  _re->clipend;
+#if 0
+	cout << "frustrum: l " << _viewplane_left << " r " << _viewplane_right
+		<< " b " << _viewplane_bottom << " t " << _viewplane_top
+		<< " n " << _z_near << " f " << _z_far << endl;
+#endif
+
 	int id = 0;
 	for(obi= (ObjectInstanceRen *) _re->instancetable.first; obi; obi=obi->next) {
 		if (!(obi->lay & _re->scene->lay & _srl->lay))
@@ -37,8 +49,8 @@
 			cout << "  Sorry, only vlak-based shapes are supported." << endl;
 	}
 
-  //Returns the built scene.
-  return _Scene;
+	//Returns the built scene.
+	return _Scene;
 }
 
 void BlenderFileLoader::insertShapeNode(ObjectRen *obr, int id)

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h	2010-01-10 11:09:30 UTC (rev 25863)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h	2010-01-10 14:08:59 UTC (rev 25864)
@@ -55,9 +55,14 @@
 protected:
 	Render* _re;
 	SceneRenderLayer* _srl;
-  NodeGroup* _Scene;
-  unsigned _numFacesRead;
-  real _minEdgeSize;
+	NodeGroup* _Scene;
+	unsigned _numFacesRead;
+	real _minEdgeSize;
+	float _viewplane_left;
+	float _viewplane_right;
+	float _viewplane_bottom;
+	float _viewplane_top;
+	float _z_near, _z_far;
 };
 
 #endif // BLENDER_FILE_LOADER_H

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp	2010-01-10 11:09:30 UTC (rev 25863)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp	2010-01-10 14:08:59 UTC (rev 25864)
@@ -19,6 +19,7 @@
 
 #include "BKE_main.h"
 #include "BLI_blenlib.h"
+#include "BLI_math.h"
 #include "BPY_extern.h"
 
 #include "renderpipeline.h"
@@ -106,6 +107,9 @@
 		for( int i = 0; i < 4; i++ )
 		   for( int j = 0; j < 4; j++ )
 			freestyle_proj[i][j] = re->winmat[i][j];
+
+		//print_m4("mv", freestyle_mv);
+		//print_m4("proj", freestyle_proj);
 	}
 
 	

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp	2010-01-10 11:09:30 UTC (rev 25863)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp	2010-01-10 14:08:59 UTC (rev 25864)
@@ -155,6 +155,7 @@
 	
   // we need to compute for each parameter t the corresponding 
   // parameter T which gives the intersection in 3D.
+#if 0
   //currentEdge = (*fe);
   Vec3r A = (fe)->vertexA()->point3D();
   Vec3r B = (fe)->vertexB()->point3D();
@@ -175,6 +176,46 @@
   
   real T;
   T = (Ic[2]*Ac[1] - Ic[1]*Ac[2])/(Ic[1]*(Bc[2]-Ac[2])-Ic[2]*(Bc[1]-Ac[1]));
+#else
+	// suffix w for world, i for image
+	Vec3r Aw = (fe)->vertexA()->point3D();
+	Vec3r Bw = (fe)->vertexB()->point3D();
+	Vec3r Ai = (fe)->vertexA()->point2D();
+	Vec3r Bi = (fe)->vertexB()->point2D();
+	Vec3r Ii = Ai + t * (Bi - Ai); // the intersection point in 2D
+	Vec3r Pw, Pi;
+	real T_sta = 0.0;
+	real T_end = 1.0;
+	real T;
+	real delta_x, delta_y, dist, dist_threshold = 1e-6;
+	int i, max_iters = 100;
+	for (i = 0; i < max_iters; i++) {
+        T = T_sta + 0.5 * (T_end - T_sta);
+        Pw = Aw + T * (Bw - Aw);
+		GeomUtils::fromWorldToImage(Pw, Pi, _transform, _viewport);
+		delta_x = Ii[0] - Pi[0];
+		delta_y = Ii[1] - Pi[1];
+        dist = sqrt(delta_x * delta_x + delta_y * delta_y);
+        if (dist < dist_threshold)
+            break;
+		if (Ai[0] < Bi[0]) {
+            if (Pi[0] < Ii[0])
+                T_sta = T;
+            else
+                T_end = T;
+		} else {
+            if (Pi[0] > Ii[0])
+                T_sta = T;
+            else
+                T_end = T;
+		}
+	}
+#if 0
+	printf("SilhouetteGeomEngine::ImageToWorldParameter(): #iters = %d, dist = %e\n", i, dist);
+#endif
+	if (i == max_iters)
+		printf("SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = %e)\n", dist);
+#endif
   
   return T;
 }

Modified: branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
===================================================================
--- branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp	2010-01-10 11:09:30 UTC (rev 25863)
+++ branches/soc-2008-mxcurioni/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp	2010-01-10 14:08:59 UTC (rev 25864)
@@ -946,14 +946,20 @@
     real tb = (*i)->tB;
 
     if((ta < -epsilon) || (ta > 1+epsilon))
-        cerr << "Warning: intersection out of range for edge " << fA->vertexA()->getId() << " - " << fA->vertexB()->getId() << endl;
+        cerr << "Warning: 2D intersection out of range for edge " << fA->vertexA()->getId() << " - " << fA->vertexB()->getId() << endl;
     
     if((tb < -epsilon) || (tb > 1+epsilon))
-        cerr << "Warning: intersection out of range for edge " << fB->vertexA()->getId() << " - " << fB->vertexB()->getId() << endl;
+        cerr << "Warning: 2D intersection out of range for edge " << fB->vertexA()->getId() << " - " << fB->vertexB()->getId() << endl;
     
     real Ta = SilhouetteGeomEngine::ImageToWorldParameter(fA, ta);
     real Tb = SilhouetteGeomEngine::ImageToWorldParameter(fB, tb);
 
+    if((Ta < -epsilon) || (Ta > 1+epsilon))
+        cerr << "Warning: 3D intersection out of range for edge " << fA->vertexA()->getId() << " - " << fA->vertexB()->getId() << endl;
+    
+    if((Tb < -epsilon) || (Tb > 1+epsilon))
+        cerr << "Warning: 3D intersection out of range for edge " << fB->vertexA()->getId() << " - " << fB->vertexB()->getId() << endl;
+
     TVertex * tvertex = ioViewMap->CreateTVertex(Vec3r(A1 + Ta*(A2-A1)), Vec3r(a1 + ta*(a2-a1)), fA, 
                                                  Vec3r(B1 + Tb*(B2-B1)), Vec3r(b1 + tb*(b2-b1)), fB, id);
      





More information about the Bf-blender-cvs mailing list