Hugin trunk 0.1
Loading...
Searching...
No Matches
MeshManager.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
23#include <wx/wx.h>
24#include <wx/platform.h>
25
26#ifdef __WXMSW__
27#include <vigra/windows.h>
28#endif
29
30#include "hugin_config.h"
31#if defined HAVE_EPOXY && HAVE_EPOXY
32#include <epoxy/gl.h>
33#else
34#include <GL/glew.h>
35#ifdef __WXMAC__
36#include <OpenGL/gl.h>
37#else
38#include <GL/gl.h>
39#endif
40#endif
41
42#include "panoinc.h"
43#include "ViewState.h"
44#include "MeshManager.h"
45#include "ChoosyRemapper.h"
46#include "LayoutRemapper.h"
47#include <iostream>
48
49
50// If we want to draw the outline of each face instead of shading it normally,
51// uncomment this. Wireframe mode is for testing mesh quality.
52// #define WIREFRAME
53
55
57 : m_pano(pano),
58 visualization_state(visualization_state),
59 layout_mode_on(false)
60{
61}
62
64{
65 for (std::vector<MeshInfo*>::iterator it = meshes.begin() ; it != meshes.end() ; ++it) {
66 delete (*it);
67 }
68 meshes.clear();
69}
70
72{
73 unsigned int old_size = meshes.size();
74 // Resize to fit if images were removed
75 while (meshes.size() > m_pano->getNrOfImages())
76 {
77 delete (meshes[meshes.size()-1]);
78 meshes.pop_back();
79 }
80 // check each existing image individualy.
81 for (unsigned int i = 0; i < meshes.size(); i++)
82 {
84 {
85 DEBUG_DEBUG("Update mesh for " << i);
86 meshes[i]->SetSrcImage(visualization_state->GetSrcImage(i));
87 meshes[i]->Update();
88 }
89 }
90 // add any new images.
91 for (unsigned int i = old_size; i < m_pano->getNrOfImages(); i++)
92 {
93 DEBUG_INFO("Making new mesh remapper for image " << i << ".");
94 //use the virtual method to get the right subclass for the MeshInfo
96 }
97}
98
99void MeshManager::RenderMesh(unsigned int image_number) const
100{
101 meshes[image_number]->CallList();
102}
103
104unsigned int MeshManager::GetDisplayList(unsigned int image_number) const
105{
106 return meshes[image_number]->display_list_number;
107}
108
110{
111 if (layout_mode_on == state) return;
112 layout_mode_on = state;
113 /* All meshes must be recalculated, since the layout mode uses meshes that
114 * do not resemble properly remapped images.
115 */
116 for (std::vector<MeshInfo*>::iterator it = meshes.begin() ; it != meshes.end() ; ++it) {
117 delete (*it);
118 }
119 meshes.clear();
120}
121
123{
124 return layout_mode_on;
125}
126
128{
129 for(unsigned int i=0;i<meshes.size();i++)
130 meshes[i]->SetScaleFactor(scale);
131};
132
133
138 : display_list_number(glGenLists(1)), // Find a free display list.
139 image(*image),
140 m_pano(m_pano_in),
141 scale_factor(3.0),
142 m_visualization_state(visualization_state_in),
143 remap(layout_mode_on_in ? (MeshRemapper *) new LayoutRemapper(m_pano, &(this->image), m_visualization_state)
144 : (MeshRemapper *) new ChoosyRemapper(m_pano, &(this->image), m_visualization_state)),
145 layout_mode_on(layout_mode_on_in)
146{
147}
148
150 // copy remap object and display list, instead of references.
151 : display_list_number(glGenLists(1)),
152 image(source.image),
154 scale_factor(3.0),
155 m_visualization_state(source.m_visualization_state),
156 remap(source.layout_mode_on ? (MeshRemapper *) new LayoutRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)
157 : (MeshRemapper *) new ChoosyRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)),
159{
160}
161
162
163
165{
166 glDeleteLists(display_list_number, 1);
167 delete remap;
168}
169
171{
172 if (layout_mode_on)
173 {
177 double scale = m_visualization_state->GetVisibleArea().width() /
178 sqrt((double) m_pano->getNrOfImages()) / scale_factor;
179 MeshRemapper & remapper_ref = *remap;
180 LayoutRemapper &r = dynamic_cast<LayoutRemapper &>(remapper_ref);
181 r.setScale(scale);
182 }
183 this->CompileList();
184}
185
187{
188 for (int x = 0 ; x < 2 ; x++) {
189 for (int y = 0 ; y < 2 ; y++) {
190 tex_coords[x][y][0] = coords.tex_c[x][y][0];
191 tex_coords[x][y][1] = coords.tex_c[x][y][1];
192 vertex_coords[x][y][0] = coords.vertex_c[x][y][0];
193 vertex_coords[x][y][1] = coords.vertex_c[x][y][1];
194 vertex_coords[x][y][2] = 0;
195 }
196 }
197}
198
200{
201 scale_factor=scale;
202 Update();
203};
204
206{
207 glCallList(display_list_number);
208}
209
211{
212 // build the display list from the coordinates generated by the remapper
213// DEBUG_INFO("Preparing to compile a display list for overview for " << image_number
214// << ".");
215 DEBUG_ASSERT(remap);
216 bool multiTexture=m_visualization_state->getViewState()->GetSupportMultiTexture();
217 unsigned int number_of_faces = 0;
218
219 DEBUG_DEBUG("mesh update compile pano");
220
221 this->BeforeCompile();
222
223 glNewList(display_list_number, GL_COMPILE);
224
225 remap->UpdateAndResetIndex();
226 DEBUG_INFO("Specifying faces in display list.");
227
228 glPushMatrix();
229
230 this->Transform();
231
232 #ifndef WIREFRAME
234 #endif
235 // get each face's coordinates from the remapper
237 while (remap->GetNextFaceCoordinates(&coords))
238 {
239 MeshCoords3D coords3d = m_visualization_state->GetMeshManager()->GetMeshCoords3D(coords);
240// DEBUG_DEBUG("mesh update " << coords3d.vertex_coords[0][0][0] << " " << coords3d.vertex_coords[0][0][1] << " " << coords3d.vertex_coords[0][0][2]);
241 number_of_faces++;
242 // go in an anticlockwise direction
243 #ifdef WIREFRAME
245 #endif
246 if(multiTexture)
247 {
248 glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][0]);
249 glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][0]);
250 }
251 else
252 glTexCoord2dv(coords3d.tex_coords[0][0]);
253 glVertex3dv(coords3d.vertex_coords[0][0]);
254 if(multiTexture)
255 {
256 glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][1]);
257 glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][1]);
258 }
259 else
260 glTexCoord2dv(coords3d.tex_coords[0][1]);
261 glVertex3dv(coords3d.vertex_coords[0][1]);
262 if(multiTexture)
263 {
264 glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][1]);
265 glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][1]);
266 }
267 else
268 glTexCoord2dv(coords3d.tex_coords[1][1]);
269 glVertex3dv(coords3d.vertex_coords[1][1]);
270 if(multiTexture)
271 {
272 glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][0]);
273 glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][0]);
274 }
275 else
276 glTexCoord2dv(coords3d.tex_coords[1][0]);
277 glVertex3dv(coords3d.vertex_coords[1][0]);
278 #ifdef WIREFRAME
279 glEnd();
280 #endif
281 }
282 #ifndef WIREFRAME
283 glEnd();
284 #endif
285
286 glPopMatrix();
287
288 glEndList();
289
290
291 this->AfterCompile();
292// DEBUG_INFO("Prepared a display list for " << image_number << ", using "
293// << number_of_faces << " face(s).");
294 DEBUG_DEBUG("after compile mesh");
295}
296
297void MeshManager::PanosphereOverviewMeshInfo::Convert(double &x, double &y, double &z, double th, double ph, double r)
298{
299 th /= 180.0;
300 th *= M_PI;
301 ph /= 180.0;
302 ph *= M_PI;
303
304 x = r * sin(th) * cos(ph);
305 y = r * sin(ph);
306 z = r * cos(th) * cos(ph);
307}
308
310{
311 yaw = image.getYaw();
312 pitch = image.getPitch();
313
314 image.setYaw(0);
315 image.setPitch(0);
316}
317
319{
320
321 glRotated(yaw, 0,-1,0);
322 glRotated(pitch, -1,0,0);
323
324}
325
327{
328 image.setYaw(yaw);
329 image.setPitch(pitch);
330}
331
333{
334 double width, height, hfov, vfov;
335 HuginBase::PanoramaOptions * opts = state->GetOptions();
336 width = opts->getWidth();
337 height = opts->getHeight();
338
339 hfov = 360;
340 vfov = 180;
341
343
344 double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
345 double th, ph;
346 th = ((coord.x / width) * hfov - hfov / 2.0);
347 ph = ((coord.y / height) * vfov - vfov / 2.0);
348
349 Convert(
350 res.x,
351 res.y,
352 res.z,
353 -th,-ph,r);
354
355 return res;
356}
357
359{
360 double width, height, hfov, vfov;
361 HuginBase::PanoramaOptions * opts = state->GetOptions();
362 width = opts->getWidth();
363 height = opts->getHeight();
364
365 hfov = 360;
366 vfov = 180;
367
368 double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
369
370 MeshCoords3D res;
371 for (int x = 0 ; x < 2 ; x++) {
372 for (int y = 0 ; y < 2 ; y++) {
373
374
375 res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
376 res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
377
378 double th, ph;
379 th = ((coords.vertex_c[x][y][0] / width) * hfov - hfov / 2.0);
380 ph = ((coords.vertex_c[x][y][1] / height) * vfov - vfov / 2.0);
381
382 Convert(
383 res.vertex_coords[x][y][0],
384 res.vertex_coords[x][y][1],
385 res.vertex_coords[x][y][2],
386 -th,-ph,r);
387
388// DEBUG_DEBUG("pano get " << res.vertex_coords[x][y][0] << " " << res.vertex_coords[x][y][1] << " " << res.vertex_coords[x][y][2]);
389// DEBUG_DEBUG("pano get " << coords.vertex_c[x][y][0] << " " << coords.vertex_c[x][y][1]);
390
391 }
392 }
393 return res;
394}
395
396
398
400{
401 double width, height;
402 HuginBase::PanoramaOptions * opts = state->GetOptions();
403 width = opts->getWidth();
404 height = opts->getHeight();
405
406 Coord3D res;
407 res.x = (coord.x - width / 2.0) * scale / width;
408 res.y = (coord.y - height / 2.0) * (-scale) / width;
409 res.z = 0;
410 return res;
411}
412
414{
415 double width, height;
416 HuginBase::PanoramaOptions * opts = state->GetOptions();
417 width = opts->getWidth();
418 height = opts->getHeight();
419
420 MeshCoords3D res;
421 for (int x = 0 ; x < 2 ; x++) {
422 for (int y = 0 ; y < 2 ; y++) {
423 res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
424 res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
425
426 res.vertex_coords[x][y][0] = (coords.vertex_c[x][y][0] - width / 2.0) * scale / width;
427 res.vertex_coords[x][y][1] = (coords.vertex_c[x][y][1] - height / 2.0) * (-scale) / width;
428 res.vertex_coords[x][y][2] = 0;
429 }
430 }
431 return res;
432
433}
434
439
444
449
450
451
#define M_PI
Define a remapper to use in the layout mode.
A ChoosyRemapper combines the other MeshRemappers and picks which one it deems is best suited for eac...
Panorama image options.
unsigned int getWidth() const
unsigned int getHeight() const
get panorama height
Model for a panorama.
Definition Panorama.h:153
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
All variables of a source image.
Draw undistored images, but with the correct centre position.
void setScale(double scale)
Set the size to draw the images.
a class to handle a 3D point
Definition MeshManager.h:94
a class to keep data of a single rectangle with texture coordinates
Handles the remapper and a display list for a specific image.
Definition MeshManager.h:65
void CallList() const
Draw the mesh.
void CompileList()
Use the remapper to create the display list.
MeshInfo(HuginBase::Panorama *m_pano, HuginBase::SrcPanoImage *image, VisualizationState *visualization_state, bool layout_mode_on)
Constructor: Creates the mesh for a given image of a panorama.
void SetScaleFactor(double scale)
void Update()
Recreate the mesh when the image or panorama it represents changes.
a subclass for the panosphere it converts coordinates obtained from an equirectangular projection to ...
static void Convert(double &x, double &y, double &z, double th, double ph, double r)
convert from spherical to cartesian coordinates
static MeshCoords3D GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState *state)
static const double scale_diff
scale factor to be used for the layout mode TODO: test this for more scenarios
static Coord3D GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState *state)
subclass for the plane overview mode.
static MeshCoords3D GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState *state)
static Coord3D GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState *state)
subclass of MeshInfo for the preview It actually does nothing in addition to the base class
void CheckUpdate()
bool layout_mode_on
bool GetLayoutMode() const
return if layout mode is active
void SetLayoutMode(bool state)
Turn layout mode on or off.
VisualizationState * visualization_state
MeshManager(HuginBase::Panorama *pano, VisualizationState *visualization_state)
HuginBase::Panorama * m_pano
virtual ~MeshManager()
void SetLayoutScale(double scale)
unsigned int GetDisplayList(unsigned int image_number) const
std::vector< MeshInfo * > meshes
virtual MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)=0
void RenderMesh(unsigned int image_number) const
A class for exchanging pointers to coordinates.
An abstract base class for objects that calculate an approximate remap specified by quadrilatrials.
MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)
MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)
MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)
virtual HuginBase::PanoramaOptions * GetOptions()
virtual HuginBase::SrcPanoImage * GetSrcImage(unsigned int image_nr)
bool RequireRecalculateMesh(unsigned int image_nr)
implementation of huginApp Class
#define DEBUG_ASSERT(cond)
Definition utils.h:80
#define DEBUG_DEBUG(msg)
Definition utils.h:68
#define DEBUG_INFO(msg)
Definition utils.h:69
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
Definition wxcms.cpp:39
include file for the hugin project
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41