ATLAS Offline Software
Loading...
Searching...
No Matches
VP1QtInventorUtils.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// //
8// Implementation of class VP1QtInventorUtils //
9// //
10// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
11// //
12// Initial version: June 2007 //
13// //
15
18#include "VP1Base/VP1Msg.h"
19
20#include "Inventor/nodes/SoMaterial.h"
21#include <Inventor/nodes/SoPerspectiveCamera.h>
22#include <Inventor/nodes/SoOrthographicCamera.h>
23#include <Inventor/nodes/SoGroup.h>
24#include <Inventor/nodes/SoNurbsCurve.h>
25#include <Inventor/nodes/SoCoordinate4.h>
26
27#include <Inventor/SoPath.h>
28#include <Inventor/SoOffscreenRenderer.h>
29#include "Inventor/Qt/SoQtRenderArea.h"
30#include <Inventor/actions/SoSearchAction.h>
31#include <Inventor/SoDB.h>
32#include <Inventor/actions/SoWriteAction.h>
33
34#include <Inventor/nodes/SoLineSet.h>
35#include <Inventor/nodes/SoVertexProperty.h>
36
37
38#include <Inventor/VRMLnodes/SoVRMLGroup.h>
39#include <Inventor/actions/SoToVRML2Action.h>
40
41#include <QDir>
42#include <QTime>
43#include <QBuffer>
44#include <QTextStream>
45#include <QSlider>
46#include <QGLFormat>
47#include <QtCoreVersion>
48
49#include <iostream>
50#include <bit>
51namespace{
52 unsigned char *
53 ucharAddress(auto * pv){
54 return reinterpret_cast<unsigned char *>(pv);
55 }
56}
57
58//____________________________________________________________________
60public:
61
62 static QImage constructImageWithTransparentBackground(const QImage& im_black_bgd, const QImage& image_white_bgd);
63
64 static void bwtorgba(unsigned char *b,unsigned char *l,int n)
65 {
66 while (n--) {
67 l[0] = *b;
68 l[1] = *b;
69 l[2] = *b;
70 l[3] = 0xff;
71 l += 4; ++b;
72 }
73 }
74
75 static void latorgba(unsigned char *b, unsigned char *a,unsigned char *l,int n)
76 {
77 while (n--) {
78 l[0] = *b;
79 l[1] = *b;
80 l[2] = *b;
81 l[3] = *a;
82 l += 4; ++b; ++a;
83 }
84 }
85
86 static void rgbtorgba(unsigned char *r,unsigned char *g,
87 unsigned char *b,unsigned char *l,int n)
88 {
89 while (n--) {
90 l[0] = r[0];
91 l[1] = g[0];
92 l[2] = b[0];
93 l[3] = 0xff;
94 l += 4; ++r; ++g; ++b;
95 }
96 }
97
98 static void rgbatorgba(unsigned char *r,unsigned char *g,
99 unsigned char *b,unsigned char *a,unsigned char *l,int n)
100 {
101 while (n--) {
102 l[0] = r[0];
103 l[1] = g[0];
104 l[2] = b[0];
105 l[3] = a[0];
106 l += 4; ++r; ++g; ++b; ++a;
107 }
108 }
109
110 typedef struct _ImageRec {
111 unsigned short imagic;
112 unsigned short type;
113 unsigned short dim;
114 unsigned short xsize, ysize, zsize;
115 unsigned int min, max;
116 unsigned int wasteBytes;
117 char name[80];
118 unsigned long colorMap;
119 FILE *file;
120 unsigned char *tmp, *tmpR, *tmpG, *tmpB;
121 unsigned long rleEnd;
122 unsigned int *rowStart;
125
126 static void ConvertLong(unsigned *array, long length)
127 {
128 while (length--) {
129 *array = std::byteswap (*array);
130 ++array;
131 }
132 }
133
134 static ImageRec *ImageOpen(const char *fileName)
135 {
136
137 ImageRec *image;
138 const bool swapFlag = std::endian::native == std::endian::little;
139 image = (ImageRec *)malloc(sizeof(ImageRec));
140 if (!image) {
141 fprintf(stderr, "Out of memory!\n");
142 exit(1);
143 }
144 if (!(image->file = fopen(fileName, "rb"))) {
145 perror(fileName);
146 free(image);
147 exit(1);
148 }
149
150 int bytesRead = fread(image, 1, 12, image->file);
151
152 if (bytesRead != 12) {
153 fprintf(stderr, "fread failed!\n");
154 fclose(image->file);
155 free(image);
156 return nullptr;
157 }
158 //what are reasonable limits on x,y,zsize?
159
160
161
162
163 if (swapFlag) {
164 image->imagic = std::byteswap (image->imagic);
165 image->type = std::byteswap (image->type);
166 image->dim = std::byteswap (image->dim);
167 image->xsize = std::byteswap (image->xsize);
168 image->ysize = std::byteswap (image->ysize);
169 image->zsize = std::byteswap (image->zsize);
170 }
171
172
173 const unsigned int colourBuffSize=image->xsize*256u;
174 image->tmp = ucharAddress(malloc(colourBuffSize));
175 image->tmpR = ucharAddress(malloc(colourBuffSize));
176 image->tmpG = ucharAddress(malloc(colourBuffSize));
177 image->tmpB = ucharAddress(malloc(colourBuffSize));
178 if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
179 image->tmpB == NULL) {
180 fprintf(stderr, "Out of memory!\n");
181 exit(1);
182 }
183
184 //should test upper limits on x here...but what is sensible? 1Mb? 100Mb?
185 if ((image->type & 0xFF00) == 0x0100) {
186 size_t x = ((size_t)image->ysize * (size_t)image->zsize) * sizeof(unsigned);
187 //cid 13609 complaining there is no input sanitising
188 //coverity[TAINTED_SCALAR]
189 image->rowStart = (unsigned *)malloc(x);
190 image->rowSize = (int *)malloc(x);
191 if (image->rowStart == NULL || image->rowSize == NULL) {
192 fprintf(stderr, "Out of memory!\n");
193 exit(1);
194 }
195 image->rleEnd = 512 + (2 * x);
196 const int fseekRetVal= fseek(image->file, 512, SEEK_SET);
197 if (fseekRetVal !=0){
198 fprintf(stderr, "Something very wrong with fseek near line 205 of VP1QtInventorUtils.cxx");
199 }
200 size_t bytesRead = 0;
201 bytesRead = fread(image->rowStart, 1, x, image->file);
202 VP1Msg::messageDebug("bytesRead(rowStart): " + QString::number(bytesRead));
203 bytesRead = fread(image->rowSize, 1, x, image->file);
204 VP1Msg::messageDebug("bytesRead(rowSize): " + QString::number(bytesRead));
205
206 if (swapFlag) {
207 ConvertLong(image->rowStart, x/(int)sizeof(unsigned));
208 ConvertLong((unsigned *)image->rowSize, x/(int)sizeof(int));
209 }
210 } else {
211 image->rowStart = NULL;
212 image->rowSize = NULL;
213 }
214 return image;
215 }
216
217 static void ImageClose(ImageRec *image)
218 {
219 fclose(image->file);
220 free(image->tmp);
221 free(image->tmpR);
222 free(image->tmpG);
223 free(image->tmpB);
224 free(image->rowSize);
225 free(image->rowStart);
226 free(image);
227 }
228
229 static void ImageGetRow(ImageRec *image,
230 unsigned char *buf, int y, int z)
231 {
232 unsigned char *iPtr, *oPtr, pixel;
233 int count;
234
235 if (image) {
236 if ((image->type & 0xFF00) == 0x0100) {
237
238 int okseek = fseek(image->file, (long)image->rowStart[y+z*image->ysize], SEEK_SET);
239 int okread = fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
240 image->file);
241
242 if (okseek != 0 || okread == 0) VP1Msg::messageDebug("fseek or fread failed!!");
243
244 iPtr = image->tmp;
245 oPtr = buf;
246 for (;;) {
247 pixel = *iPtr++;
248 count = (int)(pixel & 0x7F);
249 if (!count) {
250 return;
251 }
252 if (pixel & 0x80) {
253 while (count--) {
254 *oPtr++ = *iPtr++;
255 }
256 } else {
257 pixel = *iPtr++;
258 while (count--) {
259 *oPtr++ = pixel;
260 }
261 }
262 }
263 } else {
264 const unsigned int yDim(y*image->xsize), zDim(z*image->xsize*image->ysize);
265 int okstatus = fseek(image->file, 512u+yDim+zDim, SEEK_SET);
266 if (okstatus) { VP1Msg::messageDebug("fseek failed!!"); }
267
268 size_t bytesRead = 0;
269 bytesRead = fread(buf, 1, image->xsize, image->file);
270 VP1Msg::messageDebug("bytesRead(buf): " + QString::number(bytesRead));
271
272 }
273 }
274 else {
275 std::cout << "Warning! ImageGetRow() - no 'image'..." << std::endl;
276 }
277 }
278
279 static unsigned *read_texture(const char *name, int *width, int *height, int *components)
280 {
281 unsigned *base, *lptr;
282 unsigned char *rbuf, *gbuf, *bbuf, *abuf;
283 ImageRec *image;
284 int y;
285
286 image = ImageOpen(name);
287
288 if(!image)
289 return nullptr;
290
291 (*width)=image->xsize;
292 (*height)=image->ysize;
293 (*components)=image->zsize;
294 const unsigned int imageWidth = image->xsize;
295 const unsigned int imageHeight = image->ysize;
296 const unsigned int uintSize(sizeof(unsigned)), ucharSize(sizeof(unsigned char));
297 const unsigned int colourBufSize=imageWidth*ucharSize;
298 base = reinterpret_cast<unsigned *>(malloc(imageWidth*imageHeight*uintSize));
299 rbuf = ucharAddress(malloc(colourBufSize));
300 gbuf = ucharAddress(malloc(colourBufSize));
301 bbuf = ucharAddress(malloc(colourBufSize));
302 abuf = ucharAddress(malloc(colourBufSize));
303 if(!base || !rbuf || !gbuf || !bbuf) {
304 ImageClose(image);
305 if (base) free(base);
306 if (rbuf) free(rbuf);
307 if (gbuf) free(gbuf);
308 if (bbuf) free(bbuf);
309 if (abuf) free(abuf);
310 return NULL;
311 }
312 lptr = base;
313 for (y=0; y<image->ysize; ++y) {
314 if (image->zsize>=4) {
315 //cid 13919 complaining that there was no input sanitising
316 //coverity[TAINTED_SCALAR]
317 ImageGetRow(image,rbuf,y,0);
318 ImageGetRow(image,gbuf,y,1);
319 ImageGetRow(image,bbuf,y,2);
320 ImageGetRow(image,abuf,y,3);
321 rgbatorgba(rbuf,gbuf,bbuf,abuf,ucharAddress(lptr),image->xsize);
322 lptr += image->xsize;
323 } else if(image->zsize==3) {
324 ImageGetRow(image,rbuf,y,0);
325 ImageGetRow(image,gbuf,y,1);
326 ImageGetRow(image,bbuf,y,2);
327 rgbtorgba(rbuf,gbuf,bbuf,ucharAddress(lptr),image->xsize);
328 lptr += image->xsize;
329 } else if(image->zsize==2) {
330 ImageGetRow(image,rbuf,y,0);
331 ImageGetRow(image,abuf,y,1);
332 latorgba(rbuf,abuf,ucharAddress(lptr),image->xsize);
333 lptr += image->xsize;
334 } else {
335 ImageGetRow(image,rbuf,y,0);
336 bwtorgba(rbuf,ucharAddress(lptr),image->xsize);
337 lptr += image->xsize;
338 }
339 }
340 ImageClose(image);
341 free(rbuf);
342 free(gbuf);
343 free(bbuf);
344 free(abuf);
345
346 return (unsigned *) base;
347 }
348
349 //read/write scenegraphs:
350 static char * buffer;
351 static size_t buffer_size;
352 static void * buffer_realloc(void * bufptr, size_t size);
353 static QString buffer_writeaction(SoNode * root);
354 static void buffer_vrmlwriteaction(SoNode * root, const QString& filename);
355
357 static double allowedLineWidthMin;
358 static double allowedLineWidthMax;
360 static double allowedPointSizeMin;
361 static double allowedPointSizeMax;
363
364 //Prerender callback:
365 // static void prerendercallback_rendertoimage( void * userdata, class SoGLRenderAction * action );
366
367};
368
376
377//____________________________________________________________________
381
382//____________________________________________________________________
386
387//____________________________________________________________________
388QPixmap VP1QtInventorUtils::pixmapFromRGBFile(const QString& filename)
389{
390 return QPixmap::fromImage(imageFromRGBFile(filename));
391
392}
393
394//____________________________________________________________________
395QImage VP1QtInventorUtils::imageFromRGBFile(const QString& filename)
396{
397 int width = 0;
398 int height = 0;
399 int components = 0;
400 //more realistically, limits are probably 4'096
401 constexpr int maxheight(10'000);
402 constexpr int maxwidth(10'000);
403 auto inbounds = [](int w, int h)->bool{
404 return (w>0 and w<maxwidth) and (h>0 and h<maxheight);
405 };
406 unsigned * imagedata = Imp::read_texture(filename.toStdString().c_str(), &width, &height, &components);
407 if( not inbounds(width, height)){
408 std::cout << "VP1QtInventorUtils::imageFromRGBFile - read_texture failed?" << std::endl;
409 width = std::clamp(width, 0, maxwidth);
410 height = std::clamp(height, 0, maxheight);
411 }
412 unsigned char * data = reinterpret_cast<unsigned char*>(imagedata);
413
414 QImage im(width,height, ( components <= 3 ? QImage::Format_RGB32 : QImage::Format_ARGB32 ) );
415
416 int x{}, y{}, index{};
417 for (; y<height; ++y) {
418 for (x=0; x<width; ++x) {
419 //Fixme: Does this also work for components=1,2 4??
420 im.setPixel ( x, height-y-1, QColor( static_cast<int>(data[index]),static_cast<int>(data[index+1]),static_cast<int>(data[index+2]),static_cast<int>(data[index+3]) ).rgb() );
421 index+=4;
422 }
423 }
424 free(imagedata);
425 return im;
426}
427
428
429//____________________________________________________________________
430//QImage VP1QtInventorUtils::renderToImage(SoQtRenderArea *ra, int pixels_x, int pixels_y,
431QImage VP1QtInventorUtils::renderToImage(VP1ExaminerViewer *ra, int pixels_x, int pixels_y,
432 bool transparent_background, double actualRenderedSizeFact )
433{
434 VP1Msg::messageVerbose("VP1QtInventorUtils::renderToImage()");
435
436 if (!ra)
437 return QImage();
438
439
440 // transp,anti: Render two large, figure out transp, then resize (gives best result)
441 // transp : Render two normal, then figure out transp.
442 // : Render one normal.
443 // anti : Render one large, resize.
444
445 if (actualRenderedSizeFact!=1.0&&!transparent_background) {
446 return renderToImage(ra,
447 static_cast<int>(pixels_x*actualRenderedSizeFact+0.5),
448 static_cast<int>(pixels_y*actualRenderedSizeFact+0.5),
449 false,
450 1.0)
451 .scaled(pixels_x,pixels_y,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
452 }
453
454 if (transparent_background) {
455 //Lets make it transparent. We do this by rendering with both
456 //white and black background, and using the two results to figure
457 //out the final result.
458
459 SbColor save_bgd = ra->getBackgroundColor();
460 SbBool save_redraw = ra->isAutoRedraw();
461
462 ra->setAutoRedraw(false);
463
464
465 QImage im_black_bgd, im_white_bgd;
466 if (actualRenderedSizeFact==1.0) {
467 ra->setBackgroundColor(SbColor(0.0,0.0,0.0));
468 im_black_bgd = renderToImage(ra, pixels_x, pixels_y,false,1.0);
469 ra->setBackgroundColor(SbColor(1.0,1.0,1.0));
470 im_white_bgd = renderToImage(ra, pixels_x, pixels_y,false,1.0);
471 } else {
472 ra->setBackgroundColor(SbColor(0.0,0.0,0.0));
473 im_black_bgd = renderToImage(ra, static_cast<int>(pixels_x*actualRenderedSizeFact+0.5), static_cast<int>(pixels_y*actualRenderedSizeFact+0.5),false,1.0);
474 ra->setBackgroundColor(SbColor(1.0,1.0,1.0));
475 im_white_bgd = renderToImage(ra, static_cast<int>(pixels_x*actualRenderedSizeFact+0.5), static_cast<int>(pixels_y*actualRenderedSizeFact+0.5),false,1.0);
476 }
477
478 ra->setBackgroundColor(save_bgd);
479 ra->setAutoRedraw(save_redraw);
480
481 if (actualRenderedSizeFact==1.0)
482 return Imp::constructImageWithTransparentBackground(im_black_bgd, im_white_bgd);
483 else
484 return Imp::constructImageWithTransparentBackground(im_black_bgd, im_white_bgd)
485 .scaled(pixels_x,pixels_y,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
486 }
487
488 // DEFAULT CALL
489
490 //debug
491 int off = ra->getStereoOffsetSlot();
492 int typeSt = ra->getStereoTypeSlot();
493 VP1Msg::messageVerbose("off: " + QString::number( off ) + " - type: " + QString::number( typeSt ) );
494
495 // get the scenegraph
496 SoNode *root = ra->getSceneManager()->getSceneGraph();
497 VP1Msg::messageVerbose("got the scenegraph");
498 //std::cout << "root: " << root << std::endl;
499
500 // get the overlay scenegraph
501// SoNode *rootOverlay = ra->getOverlaySceneManager()->getSceneGraph();
502 SoNode *rootOverlay = ra->getOverlaySceneGraph();
503 VP1Msg::messageVerbose("got the overlay scenegraph");
504 //std::cout << "overlay root: " << rootOverlay << std::endl;
505
506 // set a new viewport to the preferred size
507 SbViewportRegion myViewport;
508 myViewport.setWindowSize(SbVec2s(pixels_x,pixels_y));
509
510 QString tmppath(QDir::tempPath());
511 if (!tmppath.endsWith(QDir::separator()))
512 tmppath+=QDir::separator();
513 tmppath += "vp1tmpfileXXXXXX.rgb";
514 std::string stmppath = tmppath.toStdString();
515 int tmpfd = mkstemps (stmppath.data(), 4);
516 FILE* tmpf = fdopen (tmpfd, "w");
517 QString tmpfile (stmppath.c_str());
518
519 // declare a new renderer with the viewport created above
520 SoOffscreenRenderer *myRenderer = new SoOffscreenRenderer(myViewport);
521
522 //Copy settings from the render area:
523 myRenderer->setBackgroundColor(ra->getBackgroundColor());
524
525
526 myRenderer->setComponents(SoOffscreenRenderer::RGB_TRANSPARENCY);
527 myRenderer->getGLRenderAction()->setTransparencyType(ra->getTransparencyType());
528 // myRenderer->getGLRenderAction()->addPreRenderCallback( VP1QtInventorUtils::Imp::prerendercallback_rendertoimage, 0/*userdata*/ );
529
530 // Anti-Aliasing
531 SbBool smoothing; int numPasses;
532 ra->getAntialiasing (smoothing, numPasses);
533 myRenderer->getGLRenderAction()->setSmoothing (smoothing);
534 myRenderer->getGLRenderAction()->setNumPasses(numPasses);
535
536 //Other things we could set:
537 // Overlay scenegraph.
538
539 // render the scenegraph
540 // if fails, delete the renderer and return an empty image
541 if (!myRenderer->render(root)) {
542 delete myRenderer;
543 fclose (tmpf);
544 return QImage();
545 }
546 VP1Msg::messageVerbose("rendered the scenegraph");
547
548 // render the overlay scenegraph
549 // if fails, delete the renderer and return an empty image
550 if (rootOverlay) {
551 bool okOver = myRenderer->render(rootOverlay);
552 if ( !okOver) {
553 delete myRenderer;
554 fclose (tmpf);
555 return QImage();
556 }
557 else {
558 VP1Msg::messageVerbose("rendered the overlay scenegraph");
559 }
560 }
561
562 // write the rendered image to the temp file
563 // if fails, remove the temp file and return an empty image
564 if (!myRenderer->writeToRGB(tmpf)) {
565 fclose (tmpf);
566 if (QFile::exists(tmpfile))
567 QFile(tmpfile).remove();
568 delete myRenderer;
569 return QImage();
570 }
571
572 fclose (tmpf);
573
574 // delete the renderer
575 delete myRenderer;
576
577 // get the rendered image from the temp file as a Qt QImage instance
578 QImage im(imageFromRGBFile(tmpfile));
579
580 // delete the temp file
581 if (QFile::exists(tmpfile))
582 QFile(tmpfile).remove();
583
584 // return the rendered image
585 return im;
586}
587
588//____________________________________________________________________
589//QPixmap VP1QtInventorUtils::renderToPixmap(SoQtRenderArea *ra, int pixels_x, int pixels_y,
590QPixmap VP1QtInventorUtils::renderToPixmap(VP1ExaminerViewer *ra, int pixels_x, int pixels_y,
591 bool transparent_background, double actualRenderedSizeFact )
592{
593 return QPixmap::fromImage(renderToImage(ra, pixels_x, pixels_y, transparent_background, actualRenderedSizeFact));
594}
595
596//____________________________________________________________________
597QImage VP1QtInventorUtils::Imp::constructImageWithTransparentBackground(const QImage& im_black_bgd, const QImage& im_white_bgd)
598{
599 if (im_black_bgd.isNull()||im_white_bgd.isNull()||im_black_bgd.size()!=im_white_bgd.size())
600 return QImage();
601
602 QImage im(im_black_bgd.size(),QImage::Format_ARGB32);
603
604 int width = im.width();
605 int height = im.height();
606 QRgb white = qRgba(255,255,255,255);
607 QRgb black = qRgba(0,0,0,255);
608
609 for (int x = 0; x < width; ++x)
610 for (int y = 0; y < height; ++y) {
611 if (im_black_bgd.pixel(x,y)==im_white_bgd.pixel(x,y)) {
612 im.setPixel(x,y,im_white_bgd.pixel(x,y));
613 } else if (im_black_bgd.pixel(x,y)==black&&im_white_bgd.pixel(x,y)==white) {
614 im.setPixel(x,y,Qt::transparent);
615 } else {
616 //Calculate ...
617 QColor pix_b = QColor(im_black_bgd.pixel(x,y));
618 QColor pix_w = QColor(im_white_bgd.pixel(x,y));
619 qreal alpha = 1.0 - pix_w.redF() + pix_b.redF();
620 if (alpha==0) {
621 im.setPixel(x,y,Qt::transparent);
622 } else {
623 im.setPixel(x,y,qRgba(static_cast<int>(pix_b.redF()/alpha*255+0.5),
624 static_cast<int>(pix_b.greenF()/alpha*255+0.5),
625 static_cast<int>(pix_b.blueF()/alpha*255+0.5),
626 static_cast<int>(alpha*255+0.5)));
627 }
628 }
629 }
630
631 return im;
632}
633
634
635//____________________________________________________________________
636SoGLRenderAction::TransparencyType VP1QtInventorUtils::getDefaultVP1TransparencyType()
637{
638 return SoGLRenderAction::DELAYED_BLEND;
639}
640
641//____________________________________________________________________
642QList<SoGLRenderAction::TransparencyType> VP1QtInventorUtils::getAllTransparencyTypes()
643{
644 QList<SoGLRenderAction::TransparencyType> l;
645 l << SoGLRenderAction::NONE
646 << SoGLRenderAction::SCREEN_DOOR
647 << SoGLRenderAction::ADD
648 << SoGLRenderAction::DELAYED_ADD
649 << SoGLRenderAction::SORTED_OBJECT_ADD
650 << SoGLRenderAction::BLEND
651 << SoGLRenderAction::DELAYED_BLEND
652 << SoGLRenderAction::SORTED_OBJECT_BLEND
653 << SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD
654 << SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND
655 << SoGLRenderAction::SORTED_LAYERS_BLEND;
656 return l;
657}
658
659//____________________________________________________________________
660int VP1QtInventorUtils::transparencyTypeToInt( SoGLRenderAction::TransparencyType tt )
661{
662 switch (tt) {
663 case SoGLRenderAction::SCREEN_DOOR: return 0;
664 case SoGLRenderAction::ADD: return 1;
665 case SoGLRenderAction::DELAYED_ADD: return 2;
666 case SoGLRenderAction::SORTED_OBJECT_ADD: return 3;
667 case SoGLRenderAction::BLEND: return 4;
668 case SoGLRenderAction::DELAYED_BLEND: return 5;
669 case SoGLRenderAction::SORTED_OBJECT_BLEND: return 6;
670 case SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD: return 7;
671 case SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND: return 8;
672 case SoGLRenderAction::NONE: return 9;
673 case SoGLRenderAction::SORTED_LAYERS_BLEND: return 10;
674 default:
675 VP1Msg::messageDebug("VP1QtInventorUtils::transparencyTypeToInt ERROR: Unknown transparency type");
676 return -1;
677 }
678}
679//____________________________________________________________________
680SoGLRenderAction::TransparencyType VP1QtInventorUtils::intToTransparencyType( int i )
681{
682 switch (i) {
683 case 0: return SoGLRenderAction::SCREEN_DOOR;
684 case 1: return SoGLRenderAction::ADD;
685 case 2: return SoGLRenderAction::DELAYED_ADD;
686 case 3: return SoGLRenderAction::SORTED_OBJECT_ADD;
687 case 4: return SoGLRenderAction::BLEND;
688 case 5: return SoGLRenderAction::DELAYED_BLEND;
689 case 6: return SoGLRenderAction::SORTED_OBJECT_BLEND;
690 case 7: return SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD;
691 case 8: return SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND;
692 case 9: return SoGLRenderAction::NONE;
693 case 10: return SoGLRenderAction::SORTED_LAYERS_BLEND;
694 default:
695 VP1Msg::messageDebug("VP1QtInventorUtils::intToTransparencyType ERROR: int out of range "+VP1Msg::str(i));
696 return SoGLRenderAction::DELAYED_BLEND;
697 }
698}
699
700
701//____________________________________________________________________
702QString VP1QtInventorUtils::transparencyType2PrettyString( SoGLRenderAction::TransparencyType tt )
703{
704 switch (tt) {
705 case SoGLRenderAction::DELAYED_BLEND: return "Delayed blend"; break;
706 case SoGLRenderAction::SCREEN_DOOR: return "Screen door"; break;
707 case SoGLRenderAction::ADD: return "Add"; break;
708 case SoGLRenderAction::DELAYED_ADD: return "Delayed add"; break;
709 case SoGLRenderAction::SORTED_OBJECT_ADD: return "Sorted object add"; break;
710 case SoGLRenderAction::BLEND: return "Blend (Best for Geo volumes)"; break;
711 case SoGLRenderAction::SORTED_OBJECT_BLEND: return "Sorted object blend (Best for physics objects: jets, tracks, ...)"; break;
712 case SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD: return "Sorted object sorted triangle add"; break;
713 case SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND: return "Sorted object sorted triangle blend"; break;
714 case SoGLRenderAction::NONE: return "None"; break;
715 case SoGLRenderAction::SORTED_LAYERS_BLEND: return "Sorted layers blend"; break;
716 default: return "";
717 }
718
719}
720
721//____________________________________________________________________
722QByteArray VP1QtInventorUtils::serialize( const SbRotation& rot )
723{
724
725 // ===> Setup stream writing to a byteArray:
726 QByteArray byteArray;
727 QBuffer buffer(&byteArray);
728 buffer.open(QIODevice::WriteOnly);
729 QDataStream out(&buffer);
730
731 //Write data:
732
733 float q0,q1,q2,q3;//quarternion components
734 rot.getValue (q0,q1,q2,q3);
735
736 out<<(double)q0;
737 out<<(double)q1;
738 out<<(double)q2;
739 out<<(double)q3;
740
741 if (VP1Msg::verbose()) {
742 //Fixme: check for nan's.
743 VP1Msg::messageVerbose("VP1QtInventorUtils::serialize SbRotation(q0,q1,q2,q3) = ("
744 +QString::number(q0)+", "+QString::number(q1)+", "
745 +QString::number(q2)+", "+QString::number(q3)+")");
746 }
747
748 // ===> Finish up:
749 buffer.close();
750 return byteArray;
751}
752
753//____________________________________________________________________
754bool VP1QtInventorUtils::deserialize( QByteArray& ba, SbRotation& rot )
755{
756 // ===> Setup stream for getting the contents of the byteArray:
757 QBuffer buffer(&ba);
758 buffer.open(QIODevice::ReadOnly);
759 QDataStream state(&buffer);
761 if(ba.size()==16) {
762 // Single precision
763 state.setFloatingPointPrecision(QDataStream::SinglePrecision);
764 float q0,q1,q2,q3;//quarternion components
765
766 state >> q0;
767 state >> q1;
768 state >> q2;
769 state >> q3;
770
771 rot.setValue (q0,q1,q2,q3);
772
773 if (VP1Msg::verbose()) {
774 //Fixme: check for nan's.
775 VP1Msg::messageVerbose("VP1QtInventorUtils::deserialize SbRotation(q0,q1,q2,q3) = ("
776 +QString::number(q0)+", "+QString::number(q1)+", "
777 +QString::number(q2)+", "+QString::number(q3)+")");
778 }
779 }
780 else {
781 // Double precision
782 double q0,q1,q2,q3;//quarternion components
783
784 state >> q0;
785 state >> q1;
786 state >> q2;
787 state >> q3;
788
789 rot.setValue (q0,q1,q2,q3);
790
791 if (VP1Msg::verbose()) {
792 //Fixme: check for nan's.
793 VP1Msg::messageVerbose("VP1QtInventorUtils::deserialize SbRotation(q0,q1,q2,q3) = ("
794 +QString::number(q0)+", "+QString::number(q1)+", "
795 +QString::number(q2)+", "+QString::number(q3)+")");
796 }
797 }
798
799 // ===> Finish up:
800 buffer.close();
801
802 return true;//Fixme: How to check for errors? - at least check for nan's and determinant?
803}
804
805//____________________________________________________________________
806QByteArray VP1QtInventorUtils::serialize( const SbVec3f& vec )
807{
808 // ===> Setup stream writing to a byteArray:
809 QByteArray byteArray;
810 QBuffer buffer(&byteArray);
811 buffer.open(QIODevice::WriteOnly);
812 QDataStream out(&buffer);
813
814 //Write data:
815 float x,y,z;
816 vec.getValue(x,y,z);
817 out << (double)x;
818 out << (double)y;
819 out << (double)z;
820
821 if (VP1Msg::verbose()) {
822 //Fixme: check for nan's.
823 VP1Msg::messageVerbose("VP1QtInventorUtils::serialize SbVec3f(x,y,z) = ("
824 +QString::number(x)+", "+QString::number(y)+", "+QString::number(z)+")");
825 }
826
827 // ===> Finish up:
828 buffer.close();
829 return byteArray;
830}
831
832//____________________________________________________________________
833bool VP1QtInventorUtils::deserialize( QByteArray& ba, SbVec3f& vec )
834{
835 // ===> Setup stream for getting the contents of the byteArray:
836 QBuffer buffer(&ba);
837 buffer.open(QIODevice::ReadOnly);
838 QDataStream state(&buffer);
840 if(ba.size()==12) {
841 // Single precision
842 state.setFloatingPointPrecision(QDataStream::SinglePrecision);
843 float x,y,z;
844
845 state >> x;
846 state >> y;
847 state >> z;
848
849 vec.setValue (x,y,z);
850
851 if (VP1Msg::verbose()) {
852 //Fixme: check for nan's.
853 VP1Msg::messageVerbose("VP1QtInventorUtils::deserialize SbVec3f(x,y,z) = ("
854 +QString::number(x)+", "+QString::number(y)+", "+QString::number(z)+")");
855 }
856 }
857 else {
858 double x,y,z;
859
860 state >> x;
861 state >> y;
862 state >> z;
863
864 vec.setValue (x,y,z);
865
866 if (VP1Msg::verbose()) {
867 //Fixme: check for nan's.
868 VP1Msg::messageVerbose("VP1QtInventorUtils::deserialize SbVec3f(x,y,z) = ("
869 +QString::number(x)+", "+QString::number(y)+", "+QString::number(z)+")");
870 }
871 }
872
873 // ===> Finish up:
874 buffer.close();
875
876 return true;//Fixme: How to check for errors? - at least check for nan's
877
878}
879
880//____________________________________________________________________
881QByteArray VP1QtInventorUtils::serializeSoCameraParameters( const SoCamera& cam ) {
882
883 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters start");
884
885 // ===> Setup stream writing to a byteArray:
886 QByteArray byteArray;
887 QBuffer buffer(&byteArray);
888 buffer.open(QIODevice::WriteOnly);
889 QDataStream out(&buffer);
890
891 cam.ref();
892 //Write data:
893 SbRotation camrot = cam.orientation.getValue();
894 out << serialize(camrot);
895 SbVec3f campos = cam.position.getValue();
896 out << serialize(campos);
897 float f_aspectRatio(cam.aspectRatio.getValue());
898 float f_nearDistance(cam.nearDistance.getValue());
899 float f_farDistance(cam.farDistance.getValue());
900 float f_focalDistance(cam.focalDistance.getValue());
901 out << (double)f_aspectRatio;
902 out << (double)f_nearDistance;
903 out << (double)f_farDistance;
904 out << (double)f_focalDistance;
905
906 int viewportmap(-1);
907 switch (cam.viewportMapping.getValue()) {
908 case SoCamera::CROP_VIEWPORT_FILL_FRAME: viewportmap = 0;break;
909 case SoCamera::CROP_VIEWPORT_LINE_FRAME: viewportmap = 1;break;
910 case SoCamera::CROP_VIEWPORT_NO_FRAME: viewportmap = 2;break;
911 case SoCamera::ADJUST_CAMERA: viewportmap = 3;break;
912 case SoCamera::LEAVE_ALONE: viewportmap = 4;break;
913 }
914 out << viewportmap;
915
916 //Camera type and specialised info:
917 int camtype (-1);
918 if (cam.getTypeId().isDerivedFrom(SoPerspectiveCamera::getClassTypeId()))
919 camtype = 0;
920 else if (cam.getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId()))
921 camtype = 1;
922
923 out <<camtype;
924 if (camtype==0) {
925 out << (double)static_cast<const SoPerspectiveCamera*>(&cam)->heightAngle.getValue();
926 } else if (camtype==1) {
927 out << (double)static_cast<const SoOrthographicCamera*>(&cam)->height.getValue();
928 }
929
930 cam.unrefNoDelete();
931
932 // ===> Finish up:
933 buffer.close();
934
935 if (VP1Msg::verbose()) {
936 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters aspectRatio = "+QString::number(f_aspectRatio));
937 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters nearDistance = "+QString::number(f_nearDistance));
938 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters farDistance = "+QString::number(f_farDistance));
939 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters focalDistance = "+QString::number(f_focalDistance));
940 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters viewportmap = "+QString::number(viewportmap));
941 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters camtype = "
942 +QString(camtype==0?"perspective":(camtype==1?"orthographic":"unknown")));
943 if (camtype==0)
944 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters (persp) heightAngle = "
945 +QString::number(static_cast<const SoPerspectiveCamera*>(&cam)->heightAngle.getValue()));
946 if (camtype==1)
947 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters (ortho) height = "
948 +QString::number(static_cast<const SoOrthographicCamera*>(&cam)->height.getValue()));
949 VP1Msg::messageVerbose("VP1QtInventorUtils::serializeSoCameraParameters end");
950 }
951
952 return byteArray;
953}
954
955//____________________________________________________________________
956bool VP1QtInventorUtils::deserializeSoCameraParameters( QByteArray& ba, SoCamera& cam )
957{
958 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters start");
959 if (ba==QByteArray())
960 return false;
961
962 // ===> Setup stream for getting the contents of the byteArray:
963 QBuffer buffer(&ba);
964 buffer.open(QIODevice::ReadOnly);
965 QDataStream state(&buffer);
967 if(ba.size()==64) {
968 // Single precision
969 state.setFloatingPointPrecision(QDataStream::SinglePrecision);
970
971 //Orientation:
972 SbRotation rot; QByteArray ba_rot; state >> ba_rot;
973 if (!deserialize(ba_rot,rot)) return false;
974 //position:
975 SbVec3f pos; QByteArray ba_pos; state >> ba_pos;
976 if (!deserialize(ba_pos,pos)) return false;
977
978 bool save = cam.enableNotify(false);
979 cam.ref();
980 cam.orientation.setValue(rot);
981 cam.position.setValue(pos);
982 //Misc:
983 float f_aspectRatio, f_nearDistance, f_farDistance, f_focalDistance;
984
985 state >> f_aspectRatio; cam.aspectRatio.setValue(f_aspectRatio);
986 state >> f_nearDistance; cam.nearDistance.setValue(f_nearDistance);
987 state >> f_farDistance; cam.farDistance.setValue(f_farDistance);
988 state >> f_focalDistance; cam.focalDistance.setValue(f_focalDistance);
989 //viewport mapping:
990 int viewportmap;
991 state>>viewportmap;
992 switch (viewportmap) {
993 case 0: cam.viewportMapping.setValue(SoCamera::CROP_VIEWPORT_FILL_FRAME); break;
994 case 1: cam.viewportMapping.setValue(SoCamera::CROP_VIEWPORT_LINE_FRAME);break;
995 case 2: cam.viewportMapping.setValue(SoCamera::CROP_VIEWPORT_NO_FRAME);break;
996 case 3: cam.viewportMapping.setValue(SoCamera::ADJUST_CAMERA);break;
997 case 4: cam.viewportMapping.setValue(SoCamera::LEAVE_ALONE);break;
998 //ERROR
999 }
1000
1001 bool passedcameraisperspective = cam.getTypeId().isDerivedFrom(SoPerspectiveCamera::getClassTypeId());
1002
1003 //Camera type and specialised info:
1004 int camtype;
1005 state>>camtype;
1006 float f_orthopersp_heightpar(-999);
1007 if (camtype==0) {
1008 //perspective
1009 if (!passedcameraisperspective)
1010 return false;
1011 state >> f_orthopersp_heightpar;
1012 static_cast<SoPerspectiveCamera*>(&cam)->heightAngle.setValue(f_orthopersp_heightpar);
1013 } else if (camtype==1) {
1014 //ortho
1015 if (passedcameraisperspective)
1016 return false;
1017 state >> f_orthopersp_heightpar;
1018 static_cast<SoOrthographicCamera*>(&cam)->height.setValue(f_orthopersp_heightpar);
1019 }
1020
1021 if (save) {
1022 cam.enableNotify(true);
1023 cam.touch();
1024 }
1025
1026 // ===> Finish up:
1027 buffer.close();
1028
1029 if (VP1Msg::verbose()) {
1030 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters aspectRatio = "+QString::number(f_aspectRatio));
1031 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters nearDistance = "+QString::number(f_nearDistance));
1032 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters farDistance = "+QString::number(f_farDistance));
1033 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters focalDistance = "+QString::number(f_focalDistance));
1034 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters viewportmap = "+QString::number(viewportmap));
1035 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters camtype = "
1036 +QString(camtype==0?"perspective":(camtype==1?"orthographic":"unknown")));
1037 if (camtype==0)
1038 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters (persp) heightAngle = "
1039 +QString::number(f_orthopersp_heightpar));
1040 if (camtype==1)
1041 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters (ortho) height = "
1042 +QString::number(f_orthopersp_heightpar));
1043
1044 }
1045 }
1046 else {
1047 // Double precision
1048
1049 //Orientation:
1050 SbRotation rot; QByteArray ba_rot; state >> ba_rot;
1051 if (!deserialize(ba_rot,rot)) return false;
1052 //position:
1053 SbVec3f pos; QByteArray ba_pos; state >> ba_pos;
1054 if (!deserialize(ba_pos,pos)) return false;
1055
1056 bool save = cam.enableNotify(false);
1057 cam.ref();
1058 cam.orientation.setValue(rot);
1059 cam.position.setValue(pos);
1060 //Misc:
1061 double f_aspectRatio, f_nearDistance, f_farDistance, f_focalDistance;
1062
1063 state >> f_aspectRatio; cam.aspectRatio.setValue(f_aspectRatio);
1064 state >> f_nearDistance; cam.nearDistance.setValue(f_nearDistance);
1065 state >> f_farDistance; cam.farDistance.setValue(f_farDistance);
1066 state >> f_focalDistance; cam.focalDistance.setValue(f_focalDistance);
1067 //viewport mapping:
1068 int viewportmap;
1069 state>>viewportmap;
1070 switch (viewportmap) {
1071 case 0: cam.viewportMapping.setValue(SoCamera::CROP_VIEWPORT_FILL_FRAME); break;
1072 case 1: cam.viewportMapping.setValue(SoCamera::CROP_VIEWPORT_LINE_FRAME);break;
1073 case 2: cam.viewportMapping.setValue(SoCamera::CROP_VIEWPORT_NO_FRAME);break;
1074 case 3: cam.viewportMapping.setValue(SoCamera::ADJUST_CAMERA);break;
1075 case 4: cam.viewportMapping.setValue(SoCamera::LEAVE_ALONE);break;
1076 //ERROR
1077 }
1078
1079 bool passedcameraisperspective = cam.getTypeId().isDerivedFrom(SoPerspectiveCamera::getClassTypeId());
1080
1081 //Camera type and specialised info:
1082 int camtype;
1083 state>>camtype;
1084 double f_orthopersp_heightpar(-999);
1085 if (camtype==0) {
1086 //perspective
1087 if (!passedcameraisperspective)
1088 return false;
1089 state >> f_orthopersp_heightpar;
1090 static_cast<SoPerspectiveCamera*>(&cam)->heightAngle.setValue(f_orthopersp_heightpar);
1091 } else if (camtype==1) {
1092 //ortho
1093 if (passedcameraisperspective)
1094 return false;
1095 state >> f_orthopersp_heightpar;
1096 static_cast<SoOrthographicCamera*>(&cam)->height.setValue(f_orthopersp_heightpar);
1097 }
1098
1099 if (save) {
1100 cam.enableNotify(true);
1101 cam.touch();
1102 }
1103
1104 // ===> Finish up:
1105 buffer.close();
1106
1107 if (VP1Msg::verbose()) {
1108 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters aspectRatio = "+QString::number(f_aspectRatio));
1109 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters nearDistance = "+QString::number(f_nearDistance));
1110 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters farDistance = "+QString::number(f_farDistance));
1111 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters focalDistance = "+QString::number(f_focalDistance));
1112 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters viewportmap = "+QString::number(viewportmap));
1113 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters camtype = "
1114 +QString(camtype==0?"perspective":(camtype==1?"orthographic":"unknown")));
1115 if (camtype==0)
1116 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters (persp) heightAngle = "
1117 +QString::number(f_orthopersp_heightpar));
1118 if (camtype==1)
1119 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters (ortho) height = "
1120 +QString::number(f_orthopersp_heightpar));
1121
1122 }
1123 }
1124
1125 cam.unrefNoDelete();
1126 VP1Msg::messageVerbose("VP1QtInventorUtils::deserializeSoCameraParameters end");
1127 return true;
1128}
1129
1130//____________________________________________________________________
1131SbColor VP1QtInventorUtils::qcol2sbcol(const QColor& col)
1132{
1133 return SbColor( col.red()/255.0, col.green()/255.0, col.blue()/255.0 );
1134}
1135
1136//____________________________________________________________________
1137QColor VP1QtInventorUtils::sbcol2qcol(const SbColor& col)
1138{
1139 float r,g,b;
1140 col.getValue(r,g,b);
1141 return QColor::fromRgbF( r,g,b );
1142}
1143
1144//____________________________________________________________________
1146{
1147 if (!m||m->ambientColor.getNum()!=1
1148 ||m->diffuseColor.getNum()!=1
1149 ||m->specularColor.getNum()!=1
1150 ||m->emissiveColor.getNum()!=1
1151 ||m->transparency.getNum()!=1
1152 ||m->shininess.getNum()!=1) {
1153 VP1Msg::message("VP1QtInventorUtils::serialiseSoMaterial Error: "
1154 "Passed material must have exactly one value in each of the 6 fields!!");
1155 return QByteArray();
1156 }
1157
1158
1159 // ===> Setup stream writing to a byteArray:
1160 QByteArray byteArray;
1161 QBuffer buffer(&byteArray);
1162 buffer.open(QIODevice::WriteOnly);
1163 QDataStream out(&buffer);
1164
1165 //Write data:
1166 out << QString("somat_v1_begin");
1167 out << sbcol2qcol(m->ambientColor[0]);
1168 out << sbcol2qcol(m->diffuseColor[0]);
1169 out << sbcol2qcol(m->specularColor[0]);
1170 out << sbcol2qcol(m->emissiveColor[0]);
1171 out << (double)m->shininess[0];
1172 out << (double)m->transparency[0];
1173 out << QString("somat_end");
1174
1175 // ===> Finish up:
1176 buffer.close();
1177
1178 return byteArray;
1179
1180}
1181
1182//____________________________________________________________________
1183bool VP1QtInventorUtils::deserialiseSoMaterial(QByteArray&ba,SoMaterial *&m)
1184{
1185 if (!m||m->ambientColor.getNum()!=1
1186 ||m->diffuseColor.getNum()!=1
1187 ||m->specularColor.getNum()!=1
1188 ||m->emissiveColor.getNum()!=1
1189 ||m->transparency.getNum()!=1
1190 ||m->shininess.getNum()!=1) {
1191 VP1Msg::message("VP1QtInventorUtils::deserialiseSoMaterial Error: "
1192 "Passed material must have exactly one value in each of the 6 fields!!");
1193 return false;
1194 }
1195
1196 // ===> Setup stream for getting the contents of the byteArray:
1197 QBuffer buffer(&ba);
1198 buffer.open(QIODevice::ReadOnly);
1199 QDataStream stream(&buffer);
1200 if(ba.size()==106)
1201 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
1202
1203 //Read contents while checking for validity
1204 QString str; stream >> str;
1205 if (str!="somat_v1_begin")
1206 return false;
1207
1208 QColor ambientcol; stream >> ambientcol;
1209 if (!ambientcol.isValid())
1210 return false;
1211
1212 QColor diffusecol; stream >> diffusecol;
1213 if (!diffusecol.isValid())
1214 return false;
1215
1216 QColor specularcol; stream >> specularcol;
1217 if (!specularcol.isValid())
1218 return false;
1219
1220 QColor emissivecol; stream >> emissivecol;
1221 if (!emissivecol.isValid())
1222 return false;
1223
1224 if(ba.size()==106) {
1225 // Single precision
1226 float shininess; stream >> shininess;
1227 if (shininess<0.0f||shininess>1.0f)
1228 return false;
1229
1230 float transparency; stream >> transparency;
1231 if (transparency<0.0f||transparency>1.0f)
1232 return false;
1233
1234 stream >> str;
1235 if (str!="somat_end")
1236 return false;
1237
1238 buffer.close();
1239
1240 //Apply values:
1241 m->ambientColor.setValue(qcol2sbcol(ambientcol));
1242 m->diffuseColor.setValue(qcol2sbcol(diffusecol));
1243 m->specularColor.setValue(qcol2sbcol(specularcol));
1244 m->emissiveColor.setValue(qcol2sbcol(emissivecol));
1245 m->shininess.setValue(shininess);
1246 m->transparency.setValue(transparency);
1247 }
1248 else {
1249 // Double precision
1250 double shininess; stream >> shininess;
1251 if (shininess<0.0||shininess>1.0)
1252 return false;
1253
1254 double transparency; stream >> transparency;
1255 if (transparency<0.0||transparency>1.0)
1256 return false;
1257
1258 stream >> str;
1259 if (str!="somat_end")
1260 return false;
1261
1262 buffer.close();
1263
1264 //Apply values:
1265 m->ambientColor.setValue(qcol2sbcol(ambientcol));
1266 m->diffuseColor.setValue(qcol2sbcol(diffusecol));
1267 m->specularColor.setValue(qcol2sbcol(specularcol));
1268 m->emissiveColor.setValue(qcol2sbcol(emissivecol));
1269 m->shininess.setValue(shininess);
1270 m->transparency.setValue(transparency);
1271 }
1272
1273 return true;
1274}
1275
1276//____________________________________________________________________
1277SoNode * VP1QtInventorUtils::createCircle( const double& radius )
1278{
1279 SoGroup* grp = new SoGroup;
1280 grp->ref();
1281
1282 SoCoordinate4 * coord = new SoCoordinate4;
1283 const double invsqrttwo=0.707106781186547;
1284
1285 int icoord(0);
1286 coord->point.set1Value(icoord++,SbVec4f(1*radius,0,0,1));
1287 coord->point.set1Value(icoord++,SbVec4f(invsqrttwo*radius,invsqrttwo*radius,0,invsqrttwo));
1288 coord->point.set1Value(icoord++,SbVec4f(0,1*radius,0,1));
1289 coord->point.set1Value(icoord++,SbVec4f(-invsqrttwo*radius,invsqrttwo*radius,0,invsqrttwo));
1290 coord->point.set1Value(icoord++,SbVec4f(-1*radius,0,0,1));
1291 coord->point.set1Value(icoord++,SbVec4f(-invsqrttwo*radius,-invsqrttwo*radius,0,invsqrttwo));
1292 coord->point.set1Value(icoord++,SbVec4f(0,-1*radius,0,1));
1293 coord->point.set1Value(icoord++,SbVec4f(invsqrttwo*radius,-invsqrttwo*radius,0,invsqrttwo));
1294 coord->point.set1Value(icoord++,SbVec4f(1*radius,0,0,1));
1295
1296 SoNurbsCurve * curve = new SoNurbsCurve;
1297 curve->numControlPoints = icoord;
1298
1299 int iknot(0);
1300
1301 curve->knotVector.set1Value(iknot++,0);
1302 curve->knotVector.set1Value(iknot++,0);
1303 curve->knotVector.set1Value(iknot++,0);
1304 curve->knotVector.set1Value(iknot++,1);
1305 curve->knotVector.set1Value(iknot++,1);
1306 curve->knotVector.set1Value(iknot++,2);
1307 curve->knotVector.set1Value(iknot++,2);
1308 curve->knotVector.set1Value(iknot++,3);
1309 curve->knotVector.set1Value(iknot++,3);
1310 curve->knotVector.set1Value(iknot++,4);
1311 curve->knotVector.set1Value(iknot++,4);
1312 curve->knotVector.set1Value(iknot++,4);
1313 grp->addChild(coord);
1314 grp->addChild(curve);
1315
1316 grp->unrefNoDelete();
1317 return grp;
1318}
1319
1320//____________________________________________________________________
1321SoNode * VP1QtInventorUtils::createEllipse( const double& radiusX, const double& radiusY, const int& numnodes )
1322{
1323 SoVertexProperty *vertices = new SoVertexProperty();
1324
1325 int iver(0);
1326 vertices->vertex.set1Value(iver++,radiusX,0.0,0.0);
1327 for (int i = 1; i < numnodes; i++)
1328 {
1329 vertices->vertex.set1Value(iver++,
1330 cos(2.0*static_cast<double>(i)*M_PI/static_cast<double>(numnodes))*radiusX,
1331 sin(2.0*static_cast<double>(i)*M_PI/static_cast<double>(numnodes))*radiusY,0.0);
1332 }
1333 vertices->vertex.set1Value(iver++,radiusX,0.0,0.0);
1334
1335 SoLineSet * ellipse = new SoLineSet();
1336 ellipse->numVertices = iver;
1337 ellipse->vertexProperty = vertices;
1338
1339 return ellipse;
1340}
1341
1342//_____________________________________________________________________________________
1343bool VP1QtInventorUtils::changePathTail(SoPath*path,SoNode*commonBranchPoint,SoNode*newtail)
1344{
1345 if (!path||!commonBranchPoint||!newtail)
1346 return false;
1347
1348 SoSearchAction sa;
1349 sa.setInterest(SoSearchAction::FIRST);
1350 sa.setNode(newtail);
1351 sa.apply(commonBranchPoint);
1352 //First truncate pickedPath at d->sceneroot, then append
1353 //newpath to pickedPath:
1354 SoPath * newpath = sa.getPath();
1355 if (!newpath)
1356 return false;
1357 bool found(false);
1358 for (int i=0;i<path->getLength();++i) {
1359 if (path->getNode(i)==commonBranchPoint) {
1360 found = true;
1361 path->truncate(i+1);
1362 break;
1363 }
1364 }
1365 if (found)
1366 path->append(newpath);
1367 return found;
1368}
1369
1370
1371//_____________________________________________________________________________________
1374
1375//_____________________________________________________________________________________
1377{
1378 buffer = (char *)realloc(bufptr, size);
1379 buffer_size = size;
1380 return buffer;
1381}
1382
1383//_____________________________________________________________________________________
1385{
1386 SoOutput out;
1387 buffer = (char *)malloc(1024);
1388 buffer_size = 1024;
1389 out.setBuffer(buffer, buffer_size, buffer_realloc);
1390
1391 SoWriteAction wa(&out);
1392 wa.apply(root);
1393
1394 QString s(buffer);
1395 free(buffer);
1396 return s;
1397}
1398
1399//_____________________________________________________________________________________
1400void VP1QtInventorUtils::Imp::buffer_vrmlwriteaction(SoNode * root, const QString& filename)
1401{
1402 SoToVRML2Action vwa;
1403
1404 vwa.apply(root);
1405 SoVRMLGroup * newroot = vwa.getVRML2SceneGraph();
1406
1407 SoOutput out;
1408 out.openFile(qPrintable(filename));
1409 out.setHeaderString("#VRML V2.0 utf8");
1410 SoWriteAction wra(&out);
1411 wra.apply(newroot);
1412 out.closeFile();
1413 newroot->unref();
1414 return;
1415}
1416
1417//_____________________________________________________________________________________
1418bool VP1QtInventorUtils::writeGraphToFile(SoNode*root, const QString& filename)
1419{
1420 if (!root)
1421 return false;
1422
1423 root->ref();
1424 QString s = Imp::buffer_writeaction(root);
1425 root->unrefNoDelete();
1426
1427 QFile data(filename);
1428 if (data.open(QFile::WriteOnly | QFile::Truncate)) {
1429 QTextStream out(&data);
1430#if QTCORE_VERSION >= 0x050E00
1431 out << s << Qt::endl;
1432#else
1433 out << s << endl;
1434#endif
1435 return true;
1436 } else {
1437 return false;
1438 }
1439}
1440
1441//_____________________________________________________________________________________
1442SoSeparator* VP1QtInventorUtils::readGraphFromFile(const QString& filename)
1443{
1444 // SoDB::init();
1445 SoInput in;
1446 if (!in.openFile(filename.toStdString().c_str()))
1447 return 0;
1448 return SoDB::readAll(&in);
1449}
1450
1451
1452//_____________________________________________________________________________________
1453bool VP1QtInventorUtils::writeGraphToVRMLFile(SoNode*root, const QString& filename)
1454{
1455 if (!root)
1456 return false;
1457
1458 root->ref();
1459 Imp::buffer_vrmlwriteaction(root, filename);
1460 root->unrefNoDelete();
1461
1462 // QFile data(filename);
1463 // if (data.open(QFile::WriteOnly | QFile::Truncate)) {
1464 // QTextStream out(&data);
1465 // out << s << endl;
1466 // return true;
1467 // } else {
1468 // return false;
1469 // }
1470 return true;
1471}
1472
1473
1476//_____________________________________________________________________________________
1477void VP1QtInventorUtils::setMatColor( SoMaterial * m, const double& r, const double& g, const double& b,
1478 const double& brightness, const double& transp )
1479{
1480 if (m)
1481 VP1MaterialButton::setMaterialParameters( m, r,g,b,brightness,transp );
1482}
1483
1484//_____________________________________________________________________________________
1485void VP1QtInventorUtils::setMatColor( SoMaterial * m, const QColor& col,
1486 const double& brightness, const double& transp )
1487{
1488 setMatColor( m, col.redF(), col.greenF(), col.blueF(), brightness, transp);
1489}
1490
1491
1492//_____________________________________________________________________________________
1501
1502//_____________________________________________________________________________________
1511
1512//_____________________________________________________________________________________
1514{
1516 return;
1518 QWidget * w(0);
1519 if (!ra) {
1520 VP1Msg::messageVerbose("VP1QtInventorUtils WARNING: Have to create temporary renderarea for the sole "
1521 "purpose of getting supported line widths and point sizes!");
1522 w = new QWidget(0);
1523 ra = new VP1ExaminerViewer(w);
1524 }
1525 SbVec2f range; float granularity;
1526 ra->getLineWidthLimits(range, granularity);
1527 float a,b;
1528 range.getValue(a,b);
1532 VP1Msg::messageVerbose("VP1QtInventorUtils Determined line widths supported by hardware (min,max,granularity) = ("
1533 +VP1Msg::str(a)+", "+VP1Msg::str(b)+", "+VP1Msg::str(granularity)+")");
1534 ra->getPointSizeLimits(range, granularity);
1535 range.getValue(a,b);
1539 VP1Msg::messageVerbose("VP1QtInventorUtils Determined point sizes supported by hardware (min,max,granularity) = ("
1540 +VP1Msg::str(a)+", "+VP1Msg::str(b)+", "+VP1Msg::str(granularity)+")");
1541 if (w) {
1542 delete ra;
1543 delete w;
1544 }
1545 //We clip to get a more consistent behaviour across hardware (and to limit ourselves to reasonable values:
1546
1553 if (Imp::allowedPointSizeMax>12.0)
1555}
1556
1557//_____________________________________________________________________________________
1559{
1560 if (!slider)
1561 return;
1564 int nsteps = std::min(1000,std::max<int>(0,static_cast<int>((Imp::allowedLineWidthMax-Imp::allowedLineWidthMin)/Imp::allowedLineWidthGranularity)));
1565 int stepsPerUnit = std::min(nsteps,std::max<int>(1,static_cast<int>(1.0/Imp::allowedLineWidthGranularity)));
1566 slider->setRange(0,nsteps);
1567 slider->setSingleStep(1);
1568 slider->setPageStep(stepsPerUnit);
1569}
1570
1571//_____________________________________________________________________________________
1573{
1574 if (!slider)
1575 return;
1578 int nsteps = std::min(1000,std::max<int>(0,
1580 int stepsPerUnit = std::min(nsteps,std::max<int>(1,
1581 static_cast<int>(0.5+1.0/Imp::allowedPointSizeGranularity)));
1582 slider->setRange(0,nsteps);
1583 slider->setSingleStep(1);
1584 slider->setPageStep(stepsPerUnit);
1585}
1586
1587//_____________________________________________________________________________________
1588void VP1QtInventorUtils::setValueLineWidthSlider(QSlider * slider, const double& value)
1589{
1590 if (!slider)
1591 return;
1594 int itarget = std::min(slider->maximum(),std::max<int>(slider->minimum(),
1595 static_cast<int>(0.5+(value-Imp::allowedLineWidthMin)/Imp::allowedLineWidthGranularity)));
1596 if (slider->value()!=itarget)
1597 slider->setValue(itarget);
1598}
1599
1600//_____________________________________________________________________________________
1601void VP1QtInventorUtils::setValuePointSizeSlider(QSlider * slider, const double& value)
1602{
1603 if (!slider)
1604 return;
1607 int itarget = std::min(slider->maximum(),std::max<int>(slider->minimum(),
1608 static_cast<int>(0.5+(value-Imp::allowedPointSizeMin)/Imp::allowedPointSizeGranularity)));
1609 if (slider->value()!=itarget)
1610 slider->setValue(itarget);
1611}
1612
1613//_____________________________________________________________________________________
1615{
1616 if (!slider)
1617 return 1.0;
1620 return std::max(Imp::allowedLineWidthMin,std::min(Imp::allowedLineWidthMax,
1622}
1623
1624//_____________________________________________________________________________________
1626{
1627 if (!slider)
1628 return 1.0;
1631 return std::max(Imp::allowedPointSizeMin,std::min(Imp::allowedPointSizeMax,
1633}
#define M_PI
std::vector< size_t > vec
double length(const pvec &v)
double coord
Type of coordination system.
static Double_t a
size_t size() const
Number of registered mappings.
const double width
#define y
#define x
#define z
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
Header file for AthHistogramAlgorithm.
SoQtViewer::StereoType getStereoTypeSlot(void) const
virtual SoNode * getSceneGraph()
static void setMaterialParameters(SoMaterial *m, const QColor &, const double &brightness=0.0, const double &transp=0.0)
static void messageVerbose(const QString &)
Definition VP1Msg.cxx:84
static bool verbose()
Definition VP1Msg.h:31
static void messageDebug(const QString &)
Definition VP1Msg.cxx:39
static void message(const QString &, IVP1System *sys=0)
Definition VP1Msg.cxx:30
static void buffer_vrmlwriteaction(SoNode *root, const QString &filename)
static QString buffer_writeaction(SoNode *root)
static unsigned * read_texture(const char *name, int *width, int *height, int *components)
static void * buffer_realloc(void *bufptr, size_t size)
static void rgbatorgba(unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a, unsigned char *l, int n)
static double allowedPointSizeGranularity
static double allowedLineWidthGranularity
static void ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z)
static void latorgba(unsigned char *b, unsigned char *a, unsigned char *l, int n)
static void rgbtorgba(unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *l, int n)
struct VP1QtInventorUtils::Imp::_ImageRec ImageRec
static QImage constructImageWithTransparentBackground(const QImage &im_black_bgd, const QImage &image_white_bgd)
static void ImageClose(ImageRec *image)
static void bwtorgba(unsigned char *b, unsigned char *l, int n)
static void ConvertLong(unsigned *array, long length)
static ImageRec * ImageOpen(const char *fileName)
static bool writeGraphToVRMLFile(SoNode *root, const QString &filename)
static bool deserialiseSoMaterial(QByteArray &, SoMaterial *&)
static void ensureInitLineWidthAndPointSize(SoQtRenderArea *)
static QByteArray serialiseSoMaterial(SoMaterial *)
static double getValueLineWidthSlider(const QSlider *)
static QList< SoGLRenderAction::TransparencyType > getAllTransparencyTypes()
static QByteArray serialize(const SbRotation &)
static void setLimitsLineWidthSlider(QSlider *)
static void setMatColor(SoMaterial *, const double &r, const double &g, const double &b, const double &brightness=0.0, const double &transp=0.0)
static QImage imageFromRGBFile(const QString &filename)
static QPixmap renderToPixmap(VP1ExaminerViewer *ra, int pixels_x, int pixels_y, bool transparent_background=false, double actualRenderedSizeFact=1.0)
static SoGLRenderAction::TransparencyType intToTransparencyType(int)
static void getLineWidthRanges(double &min, double &max, double &granularity)
static double getValuePointSizeSlider(const QSlider *)
static QColor sbcol2qcol(const SbColor &)
static void setValuePointSizeSlider(QSlider *, const double &value)
static QByteArray serializeSoCameraParameters(const SoCamera &)
static bool writeGraphToFile(SoNode *root, const QString &filename)
static SoNode * createCircle(const double &radius)
static bool deserialize(QByteArray &, SbRotation &)
static SbColor qcol2sbcol(const QColor &)
static bool changePathTail(SoPath *path, SoNode *commonBranchPoint, SoNode *newtail)
static QString transparencyType2PrettyString(SoGLRenderAction::TransparencyType)
static void setLimitsPointSizeSlider(QSlider *)
static SoNode * createEllipse(const double &radiusX, const double &radiusY, const int &numnodes=12)
static bool deserializeSoCameraParameters(QByteArray &, SoCamera &)
static void getPointSizeRanges(double &min, double &max, double &granularity)
static void setValueLineWidthSlider(QSlider *, const double &value)
static QImage renderToImage(VP1ExaminerViewer *ra, int pixels_x, int pixels_y, bool transparent_background=false, double actualRenderedSizeFact=1.0)
static SoSeparator * readGraphFromFile(const QString &filename)
static int transparencyTypeToInt(SoGLRenderAction::TransparencyType)
static SoGLRenderAction::TransparencyType getDefaultVP1TransparencyType()
static QPixmap pixmapFromRGBFile(const QString &filename)
static QString str(const QString &s)
Definition VP1String.h:49
int r
Definition globals.cxx:22
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
std::string base
Definition hcg.cxx:83
Definition index.py:1