Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions pptk/viewer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
#include "viewer.h"

int main(int argc, char* argv[]) {
if (argc != 2) {
qDebug() << "usage: viewer <port number>";
if ((argc != 2)&&(argc != 4)) {
qDebug() << "usage: viewer <port number> <resolutionx> <resolutiony>";
return 1;
}
QApplication a(argc, argv);
unsigned short clientPort = (unsigned short)atoi(argv[1]);
Viewer viewer(clientPort);
viewer.resize(512, 512);
if (argc>3)
{
viewer.resize((unsigned short)atoi(argv[2]), (unsigned short)atoi(argv[3]));
}else
{
viewer.resize(512, 512);
}
viewer.create();
viewer.show();

Expand Down
94 changes: 65 additions & 29 deletions pptk/viewer/viewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ class Viewer : public QWindow, protected OpenGLFuncs {

// initalize various states
_socket_waiting_on_enter_key = NULL;
_socket_waiting_on_screenshot = NULL;
_timer_fine_render_delay = NULL;
_fine_render_state = INACTIVE;
_render_state = FAST;
_render_time = std::numeric_limits<double>::infinity();
_show_text = true;

Expand Down Expand Up @@ -403,6 +405,10 @@ class Viewer : public QWindow, protected OpenGLFuncs {
if (payloadLength != sizeof(float)) break;
float r = *(float*)&payload[0];
_camera.setCameraDistance(qMax(0.1f, r));
} else if (!strcmp(propertyName.c_str(), "vFOV")) {
if (payloadLength != sizeof(float)) break;
float fov = *(float*)&payload[0];
_camera.setVerticalFOV(fov);
} else if (!strcmp(propertyName.c_str(), "selected")) {
quint64 num_selected = payloadLength / sizeof(unsigned int);
if (payloadLength != num_selected * sizeof(unsigned int)) break;
Expand All @@ -426,7 +432,12 @@ class Viewer : public QWindow, protected OpenGLFuncs {
} else if (!strcmp(propertyName.c_str(), "curr_attribute_id")) {
if (payloadLength != sizeof(unsigned int)) break;
_points->setCurrentAttributeIndex(*(unsigned int*)&payload[0]);
} else {
} else if (!strcmp(propertyName.c_str(), "window_size")) {
if (payloadLength != sizeof(unsigned int) * 2) break;
unsigned int* v = (unsigned int*)&payload[0];
resize( v[0], v[1]);
}
else {
// unrecognized property name, do nothing
// todo: consider doing something
}
Expand Down Expand Up @@ -508,7 +519,10 @@ class Viewer : public QWindow, protected OpenGLFuncs {
// receive property name string
std::string filename(stringLength, 'x');
comm::receiveBytes((char*)&filename[0], stringLength, clientConnection);
printScreen(filename);
_socket_waiting_on_screenshot = clientConnection;
screenshot(filename);
return;
//captureCameraAnimation(filename);
break;
}
case 7: { // wait for enter
Expand Down Expand Up @@ -573,7 +587,6 @@ class Viewer : public QWindow, protected OpenGLFuncs {
_dolly->setRepeat(repeat);
_dolly->start();
playCameraAnimation();

break;
}
case 10: { // set per point attributes
Expand Down Expand Up @@ -679,6 +692,7 @@ class Viewer : public QWindow, protected OpenGLFuncs {
_context->doneCurrent();
#endif
_fine_render_state = INACTIVE;
_render_state = FINE;
break;
}
case TERMINATE: {
Expand Down Expand Up @@ -706,39 +720,51 @@ class Viewer : public QWindow, protected OpenGLFuncs {
QTimer::singleShot(15, this, SLOT(playCameraAnimation()));
}

void capture() {
if (_render_state == FINE){
_context->makeCurrent(this);
int w = width() * this->devicePixelRatio();
int h = height() * this->devicePixelRatio();
GLubyte* pixels = new GLubyte[4 * w * h];
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//glReadBuffer(GL_FRONT); // otherwise will read back buffer
glReadBuffer(GL_BACK); // otherwise will read back buffer
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
QImage image(w, h, QImage::Format_ARGB32);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int index = j * 4 + (h - i - 1) * w * 4;
QColor color(pixels[index + 0],
pixels[index + 1],
pixels[index + 2],
pixels[index + 3]);
image.setPixel(j, i, color.rgba());
}
}
// expect absolute filename path
QString qstr_filename = QString::fromStdString(captureFilename);
image.save(qstr_filename);
delete[] pixels;
_context->doneCurrent();

const char* msg = "c";
comm::sendBytes(msg, 1, _socket_waiting_on_screenshot);
_socket_waiting_on_screenshot->disconnectFromHost();
_socket_waiting_on_screenshot = NULL;
}else
{
QTimer::singleShot(0, this, SLOT(capture()));
}
}

private:
void dummyCalculation(int n) {
_dummy_accumulator /= (float)n;
for (int i = 0; i < n; i++)
_dummy_accumulator += sqrtf(pow(6.9f, log((float)i)));
}

void printScreen(std::string filename) {
_context->makeCurrent(this);
int w = width() * this->devicePixelRatio();
int h = height() * this->devicePixelRatio();
GLubyte* pixels = new GLubyte[4 * w * h];
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glReadBuffer(GL_FRONT); // otherwise will read back buffer
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
QImage image(w, h, QImage::Format_ARGB32);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int index = j * 4 + (h - i - 1) * w * 4;
QColor color(pixels[index + 0],
pixels[index + 1],
pixels[index + 2],
pixels[index + 3]);
image.setPixel(j, i, color.rgba());
}
}
// expect absolute filename path
QString qstr_filename = QString::fromStdString(filename);
image.save(qstr_filename);
delete[] pixels;
_context->doneCurrent();
}

void displayInfo() {
if (!_show_text) return;
Expand Down Expand Up @@ -873,6 +899,12 @@ class Viewer : public QWindow, protected OpenGLFuncs {
displayInfo();
if (this->isExposed()) _context->swapBuffers(this);
_context->doneCurrent();
_render_state = FAST;
}

void screenshot(std::string filename) {
captureFilename = filename;
QTimer::singleShot(0, this, SLOT(capture()));
}

QPointF win2ndc(QPointF p) {
Expand All @@ -898,14 +930,18 @@ class Viewer : public QWindow, protected OpenGLFuncs {
float _dummy_accumulator;
enum FineRenderState { INACTIVE, INITIALIZE, CHUNK, FINALIZE, TERMINATE };
FineRenderState _fine_render_state;
enum RenderState { FAST, FINE };
RenderState _render_state;
QTimer* _timer_fine_render_delay;
std::size_t _chunk_offset;
std::size_t _max_chunk_size;
std::vector<unsigned int> _refined_indices;

QTcpSocket* _socket_waiting_on_enter_key;
QTcpSocket* _socket_waiting_on_screenshot;
double _render_time;
bool _show_text;
std::string captureFilename;
};

#endif // __VIEWER_H__
17 changes: 14 additions & 3 deletions pptk/viewer/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self, *args, **kwargs):
s.bind(('localhost', 0))
s.listen(0)
self._process = subprocess.Popen(
[os.path.join(_viewer_dir, 'viewer'), str(s.getsockname()[1])],
[os.path.join(_viewer_dir, 'viewer'), str(s.getsockname()[1]),'100','1000'],
stdout=subprocess.PIPE,
stderr=(None if debug else subprocess.PIPE))
if debug:
Expand Down Expand Up @@ -121,6 +121,8 @@ def set(self, **kwargs):
show_info bool Show information text overlay
show_axis bool Show axis / look-at cursor
theta float32 Camera elevation angle (radians)
vFOV float32 Camera vertical field of view
window_size 2 x uint set window size
================= =============== =================================

(phi, theta, r) are spherical coordinates specifying camera position
Expand Down Expand Up @@ -295,7 +297,7 @@ def capture(self, filename):

"""
msg = struct.pack('b', 6) + _pack_string(os.path.abspath(filename))
self.__send(msg)
self.__send(msg, True)

def play(self, poses, ts=[], tlim=[-numpy.inf, numpy.inf], repeat=False,
interp='cubic_natural'):
Expand Down Expand Up @@ -440,7 +442,7 @@ def __load(self, positions):
# send message to viewer
self.__send(msg)

def __send(self, msg):
def __send(self, msg, blocking = False):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', self._portNumber))
totalSent = 0
Expand All @@ -449,6 +451,13 @@ def __send(self, msg):
if sent == 0:
raise RuntimeError("socket connection broken")
totalSent = totalSent + sent
if blocking:
s.setblocking(1)
buf = b''
while len(buf) == 0:
buf += s.recv(1)
if buf != b'c':
raise RuntimeError('expecting return code \'c\'')
s.close()

def __query(self, msg):
Expand Down Expand Up @@ -601,10 +610,12 @@ def _init_properties():
_properties['phi'] = _encode_float
_properties['theta'] = _encode_float
_properties['r'] = _encode_float
_properties['vFOV'] = _encode_float
_properties['selected'] = _encode_uints
_properties['color_map'] = _encode_rgbas
_properties['color_map_scale'] = _encode_floats
_properties['curr_attribute_id'] = _encode_uint
_properties['window_size'] = _encode_uints


def _construct_get_msg(prop_name):
Expand Down