Blender  V2.93
SilhouetteGeomEngine.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
23 #include <cstdio>
24 #include <cstring>
25 
26 #include "Silhouette.h"
27 #include "SilhouetteGeomEngine.h"
28 
29 #include "../geometry/GeomUtils.h"
30 
31 #include "BKE_global.h"
32 
33 using namespace std;
34 
35 namespace Freestyle {
36 
37 Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0, 0, 0);
38 real SilhouetteGeomEngine::_translation[3] = {0, 0, 0};
39 real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {
40  {1, 0, 0, 0},
41  {0, 1, 0, 0},
42  {0, 0, 1, 0},
43  {0, 0, 0, 1},
44 };
45 real SilhouetteGeomEngine::_projectionMatrix[4][4] = {
46  {1, 0, 0, 0},
47  {0, 1, 0, 0},
48  {0, 0, 1, 0},
49  {0, 0, 0, 1},
50 };
51 real SilhouetteGeomEngine::_transform[4][4] = {
52  {1, 0, 0, 0},
53  {0, 1, 0, 0},
54  {0, 0, 1, 0},
55  {0, 0, 0, 1},
56 };
57 int SilhouetteGeomEngine::_viewport[4] = {1, 1, 1, 1};
58 real SilhouetteGeomEngine::_Focal = 0.0;
59 
60 real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {
61  {1, 0, 0, 0},
62  {0, 1, 0, 0},
63  {0, 0, 1, 0},
64  {0, 0, 0, 1},
65 };
66 real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {
67  {1, 0, 0, 0},
68  {0, 1, 0, 0},
69  {0, 0, 1, 0},
70  {0, 0, 0, 1},
71 };
72 real SilhouetteGeomEngine::_znear = 0.0;
73 real SilhouetteGeomEngine::_zfar = 100.0;
74 bool SilhouetteGeomEngine::_isOrthographicProjection = false;
75 
76 SilhouetteGeomEngine *SilhouetteGeomEngine::_pInstance = nullptr;
77 
78 void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4],
79  const real iProjectionMatrix[4][4],
80  const int iViewport[4],
81  real iFocal)
82 {
83  unsigned int i, j;
84  _translation[0] = iModelViewMatrix[3][0];
85  _translation[1] = iModelViewMatrix[3][1];
86  _translation[2] = iModelViewMatrix[3][2];
87 
88  for (i = 0; i < 4; i++) {
89  for (j = 0; j < 4; j++) {
90  _modelViewMatrix[i][j] = iModelViewMatrix[j][i];
91  _glModelViewMatrix[i][j] = iModelViewMatrix[i][j];
92  }
93  }
94 
95  for (i = 0; i < 4; i++) {
96  for (j = 0; j < 4; j++) {
97  _projectionMatrix[i][j] = iProjectionMatrix[j][i];
98  _glProjectionMatrix[i][j] = iProjectionMatrix[i][j];
99  }
100  }
101 
102  for (i = 0; i < 4; i++) {
103  for (j = 0; j < 4; j++) {
104  _transform[i][j] = 0;
105  for (unsigned int k = 0; k < 4; k++) {
106  _transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j];
107  }
108  }
109  }
110 
111  for (i = 0; i < 4; i++) {
112  _viewport[i] = iViewport[i];
113  }
114  _Focal = iFocal;
115 
116  _isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0);
117 }
118 
119 void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar)
120 {
121  _znear = iZNear;
122  _zfar = iZFar;
123 }
124 
125 void SilhouetteGeomEngine::retrieveViewport(int viewport[4])
126 {
127  memcpy(viewport, _viewport, sizeof(int[4]));
128 }
129 
130 void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex *> &ioVertices)
131 {
132  Vec3r newPoint;
133  vector<SVertex *>::iterator sv, svend;
134  for (sv = ioVertices.begin(), svend = ioVertices.end(); sv != svend; sv++) {
136  (*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
137  (*sv)->setPoint2D(newPoint);
138  }
139 }
140 
141 void SilhouetteGeomEngine::ProjectSilhouette(SVertex *ioVertex)
142 {
143  Vec3r newPoint;
145  ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport);
146  ioVertex->setPoint2D(newPoint);
147 }
148 
149 real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t)
150 {
151  if (_isOrthographicProjection) {
152  return t;
153  }
154 
155  // we need to compute for each parameter t the corresponding parameter T which gives the
156  // intersection in 3D.
157  real T;
158 
159  // suffix w for world, c for camera, r for retina, i for image
160  Vec3r Aw = (fe)->vertexA()->point3D();
161  Vec3r Bw = (fe)->vertexB()->point3D();
162  Vec3r Ac, Bc;
163  GeomUtils::fromWorldToCamera(Aw, Ac, _modelViewMatrix);
164  GeomUtils::fromWorldToCamera(Bw, Bc, _modelViewMatrix);
165  Vec3r ABc = Bc - Ac;
166 #if 0
167  if (G.debug & G_DEBUG_FREESTYLE) {
168  cout << "Ac " << Ac << endl;
169  cout << "Bc " << Bc << endl;
170  cout << "ABc " << ABc << endl;
171  }
172 #endif
173  Vec3r Ai = (fe)->vertexA()->point2D();
174  Vec3r Bi = (fe)->vertexB()->point2D();
175  Vec3r Ii = Ai + t * (Bi - Ai); // the intersection point in the 2D image space
176  Vec3r Ir, Ic;
177  GeomUtils::fromImageToRetina(Ii, Ir, _viewport);
178 
179  real alpha, beta, denom;
180  real m11 = _projectionMatrix[0][0];
181  real m13 = _projectionMatrix[0][2];
182  real m22 = _projectionMatrix[1][1];
183  real m23 = _projectionMatrix[1][2];
184 
185  if (fabs(ABc[0]) > 1.0e-6) {
186  alpha = ABc[2] / ABc[0];
187  beta = Ac[2] - alpha * Ac[0];
188  denom = alpha * (Ir[0] + m13) + m11;
189  if (fabs(denom) < 1.0e-6) {
190  goto iter;
191  }
192  Ic[0] = -beta * (Ir[0] + m13) / denom;
193 #if 0
194  Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22;
195  Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2];
196 #endif
197  T = (Ic[0] - Ac[0]) / ABc[0];
198  }
199  else if (fabs(ABc[1]) > 1.0e-6) {
200  alpha = ABc[2] / ABc[1];
201  beta = Ac[2] - alpha * Ac[1];
202  denom = alpha * (Ir[1] + m23) + m22;
203  if (fabs(denom) < 1.0e-6) {
204  goto iter;
205  }
206  Ic[1] = -beta * (Ir[1] + m23) / denom;
207 #if 0
208  Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11;
209  Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2];
210 #endif
211  T = (Ic[1] - Ac[1]) / ABc[1];
212  }
213  else {
214  iter:
215  bool x_coords, less_than;
216  if (fabs(Bi[0] - Ai[0]) > 1.0e-6) {
217  x_coords = true;
218  less_than = Ai[0] < Bi[0];
219  }
220  else {
221  x_coords = false;
222  less_than = Ai[1] < Bi[1];
223  }
224  Vec3r Pc, Pr, Pi;
225  real T_sta = 0.0;
226  real T_end = 1.0;
227  real delta_x, delta_y, dist, dist_threshold = 1.0e-6;
228  int i, max_iters = 100;
229  for (i = 0; i < max_iters; i++) {
230  T = T_sta + 0.5 * (T_end - T_sta);
231  Pc = Ac + T * ABc;
232  GeomUtils::fromCameraToRetina(Pc, Pr, _projectionMatrix);
233  GeomUtils::fromRetinaToImage(Pr, Pi, _viewport);
234  delta_x = Ii[0] - Pi[0];
235  delta_y = Ii[1] - Pi[1];
236  dist = sqrt(delta_x * delta_x + delta_y * delta_y);
237  if (dist < dist_threshold) {
238  break;
239  }
240  if (x_coords) {
241  if (less_than) {
242  if (Pi[0] < Ii[0]) {
243  T_sta = T;
244  }
245  else {
246  T_end = T;
247  }
248  }
249  else {
250  if (Pi[0] > Ii[0]) {
251  T_sta = T;
252  }
253  else {
254  T_end = T;
255  }
256  }
257  }
258  else {
259  if (less_than) {
260  if (Pi[1] < Ii[1]) {
261  T_sta = T;
262  }
263  else {
264  T_end = T;
265  }
266  }
267  else {
268  if (Pi[1] > Ii[1]) {
269  T_sta = T;
270  }
271  else {
272  T_end = T;
273  }
274  }
275  }
276  }
277 #if 0
278  if (G.debug & G_DEBUG_FREESTYLE) {
279  cout << "SilhouetteGeomEngine::ImageToWorldParameter(): #iters = " << i
280  << ", dist = " << dist << "\n";
281  }
282 #endif
283  if (i == max_iters && G.debug & G_DEBUG_FREESTYLE) {
284  cout << "SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = "
285  << dist << ")\n";
286  }
287  }
288 
289  return T;
290 }
291 
292 Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r &M)
293 {
294  Vec3r newPoint;
295  GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport);
296  return newPoint;
297 }
298 
299 Vec3r SilhouetteGeomEngine::CameraToImage(const Vec3r &M)
300 {
301  Vec3r newPoint, p;
302  GeomUtils::fromCameraToRetina(M, p, _projectionMatrix);
303  GeomUtils::fromRetinaToImage(p, newPoint, _viewport);
304  return newPoint;
305 }
306 
307 } /* namespace Freestyle */
@ G_DEBUG_FREESTYLE
Definition: BKE_global.h:140
sqrt(x)+1/max(0
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Class to perform all geometric operations dedicated to silhouette. That, for example,...
Classes to define a silhouette structure.
void setPoint2D(const Vec3r &iPoint2D)
Definition: Silhouette.h:303
const Vec3r & point3D() const
Definition: Silhouette.h:237
static CCL_NAMESPACE_BEGIN const double alpha
#define M
#define T
void fromRetinaToImage(const Vec3r &p, Vec3r &q, const int viewport[4])
Definition: GeomUtils.cpp:671
void fromWorldToImage(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4], const real projection_matrix[4][4], const int viewport[4])
Definition: GeomUtils.cpp:683
void fromWorldToCamera(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4])
Definition: GeomUtils.cpp:661
void fromCameraToRetina(const Vec3r &p, Vec3r &q, const real projection_matrix[4][4])
Definition: GeomUtils.cpp:666
void fromImageToRetina(const Vec3r &p, Vec3r &q, const int viewport[4])
Definition: GeomUtils.cpp:707
VecMat::Vec3< real > Vec3r
Definition: Geom.h:42
inherits from class Rep
Definition: AppCanvas.cpp:32
double real
Definition: Precision.h:26
ccl_device_inline float beta(float x, float y)
Definition: util_math.h:666
ccl_device_inline float2 fabs(const float2 &a)
#define G(x, y, z)