1 // This is brl/bbas/bmsh3d/vis/bmsh3d_vis_utils.cxx
2 #include <iostream>
3 #include <vector>
4 #include "bmsh3d_vis_utils.h"
5 //:
6 // \file
7 // \author MingChing Chang
8 // \date May 03, 2005.
9
10 #ifdef _MSC_VER
11 # include "vcl_msvc_warnings.h"
12 #endif
13 #include <cassert>
14 #include "vnl/vnl_random.h"
15 #include "vnl/vnl_math.h"
16 #include "vgl/vgl_vector_3d.h"
17
18 #include <Inventor/nodes/SoSeparator.h>
19 #include <Inventor/nodes/SoBaseColor.h>
20 #include <Inventor/nodes/SoDrawStyle.h>
21 #include <Inventor/nodes/SoCoordinate3.h>
22 #include <Inventor/nodes/SoMaterial.h>
23 #include <Inventor/nodes/SoVertexProperty.h>
24 #include <Inventor/nodes/SoIndexedFaceSet.h>
25 #include <Inventor/nodes/SoIndexedLineSet.h>
26 #include <Inventor/nodes/SoShapeHints.h>
27 #include <Inventor/nodes/SoText2.h>
28 #include <Inventor/nodes/SoTransform.h>
29 #include <Inventor/nodes/SoTranslation.h>
30 #include <Inventor/nodes/SoRotation.h>
31 #include <Inventor/nodes/SoPointSet.h>
32 #include <Inventor/nodes/SoCube.h>
33 #include <Inventor/nodes/SoSphere.h>
34 #include <Inventor/nodes/SoCylinder.h>
35 #include <Inventor/nodes/SoLineSet.h>
36 #include <Inventor/nodes/SoFaceSet.h>
37 #include <Inventor/nodes/SoDirectionalLight.h>
38 #include <Inventor/actions/SoSearchAction.h>
39
color_from_code(const int colorcode)40 SbColor color_from_code (const int colorcode)
41 {
42 switch (colorcode)
43 {
44 case COLOR_NOT_SPECIFIED:return SbColor(0.5f, 0.5f, 0.5f);
45 case COLOR_BLACK: return SbColor(0.0f, 0.0f, 0.0f);
46 case COLOR_RED: return SbColor(1.0f, 0.0f, 0.0f);
47 case COLOR_GREEN: return SbColor(0.0f, 1.0f, 0.0f);
48 case COLOR_BLUE: return SbColor(0.0f, 0.0f, 1.0f);
49 case COLOR_YELLOW: return SbColor(1.0f, 1.0f, 0.0f);
50 case COLOR_CYAN: return SbColor(0.0f, 1.0f, 1.0f);
51 case COLOR_PINK: return SbColor(1.0f, 0.0f, 1.0f);
52 case COLOR_GRAY: return SbColor(0.6f, 0.6f, 0.6f);
53 case COLOR_DARKGRAY: return SbColor(0.4f, 0.4f, 0.4f);
54 case COLOR_DARKRED: return SbColor(0.5f, 0.0f, 0.0f);
55 case COLOR_DARKGREEN: return SbColor(0.0f, 0.5f, 0.0f);
56 case COLOR_DARKBLUE: return SbColor(0.0f, 0.0f, 0.5f);
57 case COLOR_DARKYELLOW:return SbColor(0.5f, 0.5f, 0.0f);
58 case COLOR_DARKCYAN: return SbColor(0.0f, 0.5f, 0.5f);
59 case COLOR_PURPLE: return SbColor(0.5f, 0.0f, 0.5f);
60 case COLOR_WHITE: return SbColor(1.0f, 1.0f, 1.0f);
61 case COLOR_LIGHTGRAY: return SbColor(0.6f, 0.6f, 0.6f);
62 case COLOR_GRAYBLUE: return SbColor(0.5f, 0.5f, 1.0f);
63 case COLOR_LIGHTGREEN:return SbColor(0.5f, 1.0f, 0.5f);
64 case COLOR_ORANGE: return SbColor(1.0f, 0.7f, 0.0f);
65 case COLOR_GOLD: return SbColor(0.8f, 0.7f, 0.2f);
66 case COLOR_SILVER: return SbColor(0.8f, 0.8f, 0.8f);
67 case COLOR_RANDOM: return get_next_rand_color();
68 default: assert(0); return SbColor(0.0f, 0.0f, 0.0f);
69 }
70
71 return SbColor (0.0f, 0.0f, 0.0f);
72 }
73
74 //: The scenegraph getParent function.
75 // See http://doc.coin3d.org/Coin/classSoGroup.html
getParent(SoNode * node,SoNode * root)76 SoGroup* getParent (SoNode* node, SoNode* root)
77 {
78 SoSearchAction sa;
79 sa.setNode(node);
80 sa.setInterest(SoSearchAction::FIRST);
81 sa.apply(root);
82 SoPath * p = sa.getPath();
83 assert(p && "getPath() not found");
84 if (p->getLength() < 2) {
85 return NULL;
86 } // no parent
87 return (SoGroup *) p->getNodeFromTail(1);
88 }
89
assign_rgb_light(SoSeparator * root)90 void assign_rgb_light (SoSeparator* root)
91 {
92 SoDirectionalLight* light1 = new SoDirectionalLight;
93 light1->direction = SbVec3f(1,0,0);
94 light1->color = SbColor(0.5,0,0);
95 root->addChild (light1);
96
97 SoDirectionalLight* light2 = new SoDirectionalLight;
98 light2->direction = SbVec3f(0,1,0);
99 light2->color = SbColor(0,0.5,0);
100 root->addChild (light2);
101
102 SoDirectionalLight* light3 = new SoDirectionalLight;
103 light3->direction = SbVec3f(0,0,1);
104 light3->color = SbColor(0,0,0.5);
105 root->addChild (light3);
106
107 SoDirectionalLight* light4 = new SoDirectionalLight;
108 light4->direction = SbVec3f(-1,0,0);
109 light4->color = SbColor(0.5,0,0);
110 root->addChild (light4);
111
112 SoDirectionalLight* light5 = new SoDirectionalLight;
113 light5->direction = SbVec3f(0,-1,0);
114 light5->color = SbColor(0,0.5,0);
115 root->addChild (light5);
116
117 SoDirectionalLight* light6 = new SoDirectionalLight;
118 light6->direction = SbVec3f(0,0,-1);
119 light6->color = SbColor(0,0,0.5);
120 root->addChild (light6);
121 }
122
123 // cvalue 0: blue, cvalue 1: red
get_color_tone(float cvalue)124 SbColor get_color_tone (float cvalue)
125 {
126 SbColor color;
127
128 if (cvalue < 0.25f) // From Blue to Aqua
129 color = SbColor (0.0f, cvalue*4, 1.0f);
130 else if (cvalue < 0.5f) // From Aqua to Green
131 color = SbColor (0.0f, 1.0f, (0.5f-cvalue)*4);
132 else if (cvalue < 0.75f) // From Green to Yellow
133 color = SbColor ((cvalue-0.5f)*4, 1.0f, 0.0f);
134 else // From Yellow to Red
135 color = SbColor (1.0f, (1.0f-cvalue)*4, 0.0f);
136
137 return color;
138 }
139
generate_color_table(unsigned long seed,unsigned int size,std::vector<SbColor> & color_table)140 void generate_color_table (unsigned long seed, unsigned int size,
141 std::vector<SbColor>& color_table)
142 {
143 color_table.clear();
144
145 //: initialize the random color by given seed
146 init_rand_color (seed);
147
148 for (unsigned int i=0; i<size; i++) {
149 //: generate a random color and store it
150 SbColor color = get_next_rand_color ();
151 color_table.push_back (color);
152 }
153 }
154
155 // #######################################################
156
draw_cube_geom(const float x,const float y,const float z,const float size)157 SoSeparator* draw_cube_geom (const float x, const float y, const float z,
158 const float size)
159 {
160 SoSeparator* root = new SoSeparator;
161
162 SoTranslation* trans = new SoTranslation;
163 trans->translation.setValue (SbVec3f(x, y, z));
164 root->addChild (trans);
165
166 SoCube* cube = new SoCube ();
167 cube->width = size;
168 cube->height = size;
169 cube->depth = size;
170 root->addChild (cube);
171
172 return root;
173 }
174
draw_cube_geom(const vgl_point_3d<double> pt,const float size)175 SoSeparator* draw_cube_geom (const vgl_point_3d<double> pt, const float size)
176 {
177 return draw_cube_geom ((float)pt.x(), (float)pt.y(), (float)pt.z(), size);
178 }
179
draw_cube(const float x,const float y,const float z,const float size,const SbColor & color)180 SoSeparator* draw_cube (const float x, const float y, const float z,
181 const float size, const SbColor& color)
182 {
183 SoSeparator* root = new SoSeparator;
184
185 // color
186 SoBaseColor *basecolor = new SoBaseColor;
187 basecolor->rgb = color;
188 root->addChild (basecolor);
189
190 SoTranslation* trans = new SoTranslation;
191 trans->translation.setValue (SbVec3f(x, y, z));
192 root->addChild (trans);
193
194 SoCube* cube = new SoCube ();
195 cube->width = size;
196 cube->height = size;
197 cube->depth = size;
198 root->addChild (cube);
199
200 return root;
201 }
202
draw_cube(const vgl_point_3d<double> pt,const float size,const SbColor & color)203 SoSeparator* draw_cube (const vgl_point_3d<double> pt,
204 const float size, const SbColor& color)
205 {
206 return draw_cube ((float)pt.x(), (float)pt.y(), (float)pt.z(), size, color);
207 }
208
draw_sphere_geom(const float x,const float y,const float z,const float radius)209 SoSeparator* draw_sphere_geom (const float x, const float y, const float z,
210 const float radius)
211 {
212 SoSeparator* root = new SoSeparator;
213
214 SoTranslation* trans = new SoTranslation;
215 trans->translation.setValue (SbVec3f(x, y, z));
216 root->addChild (trans);
217
218 SoSphere* sphere = new SoSphere ();
219 sphere->radius = radius;
220 root->addChild (sphere);
221
222 return root;
223 }
224
draw_sphere_geom(const vgl_point_3d<double> pt,const float radius)225 SoSeparator* draw_sphere_geom (const vgl_point_3d<double> pt, const float radius)
226 {
227 return draw_sphere_geom ((float)pt.x(), (float)pt.y(), (float)pt.z(), radius);
228 }
229
draw_sphere(const float x,const float y,const float z,const float radius,const SbColor & color)230 SoSeparator* draw_sphere (const float x, const float y, const float z,
231 const float radius, const SbColor& color)
232 {
233 SoSeparator* root = new SoSeparator;
234
235 SoBaseColor *basecolor = new SoBaseColor;
236 basecolor->rgb = color;
237 root->addChild (basecolor);
238
239 SoTranslation* trans = new SoTranslation;
240 trans->translation.setValue (SbVec3f(x, y, z));
241 root->addChild (trans);
242
243 SoSphere* sphere = new SoSphere ();
244 sphere->radius = radius;
245 root->addChild (sphere);
246
247 return root;
248 }
249
draw_sphere(const vgl_point_3d<double> pt,const float radius,const SbColor & color)250 SoSeparator* draw_sphere (const vgl_point_3d<double> pt,
251 const float radius, const SbColor& color)
252 {
253 return draw_sphere ((float)pt.x(), (float)pt.y(), (float)pt.z(), radius, color);
254 }
255
256
257 //: draw a cylinder, given the radius, the coordinates of the start and end points of the centerline
draw_cylinder(float x1,float y1,float z1,float x2,float y2,float z2,float radius,const SbColor & color,float transparency)258 SoSeparator* draw_cylinder(float x1, float y1, float z1,
259 float x2, float y2, float z2,
260 float radius,
261 const SbColor& color,
262 float transparency)
263 {
264 SoSeparator* root = new SoSeparator;
265 #if 0
266 // color
267 SoBaseColor *basecolor = new SoBaseColor;
268 basecolor->rgb = color;
269 root->addChild (basecolor);
270 #endif // 0
271 // Create a SoMaterial to draw color in detail.
272 SoMaterial *material = new SoMaterial;
273 material->diffuseColor.setValue (color);
274 material->emissiveColor.setValue(color/2);
275 material->transparency = transparency;
276 root->addChild (material);
277
278 // translation
279 SoTranslation* trans = new SoTranslation;
280 trans->translation.setValue (SbVec3f(x1, y1, z1));
281 root->addChild (trans);
282
283 // rotaiton
284 SoRotation* rot = new SoRotation;
285
286 vgl_vector_3d<float > y_axis(0, 1, 0);
287 vgl_vector_3d<float > cylinder_orient(x2-x1, y2-y1, z2-z1);
288 vgl_vector_3d<float > rot_axis = cross_product(y_axis, cylinder_orient);
289 float rot_angle = (float)angle(y_axis, cylinder_orient);
290
291 rot->rotation.setValue(SbVec3f(rot_axis.x(), rot_axis.y(), rot_axis.z()), rot_angle);
292 root->addChild (rot);
293
294 SoCylinder* cylinder = new SoCylinder();
295 cylinder->radius = radius;
296 cylinder->height = std::sqrt(vnl_math::sqr(x2-x1) +
297 vnl_math::sqr(y2-y1) +
298 vnl_math::sqr(z2-z1));
299
300 root->addChild(cylinder);
301 return root;
302 }
303
draw_cylinder(const vgl_point_3d<double> & centerline_start,const vgl_point_3d<double> & centerline_end,float radius,const SbColor & color,float transparency)304 SoSeparator* draw_cylinder(const vgl_point_3d<double>& centerline_start,
305 const vgl_point_3d<double>& centerline_end,
306 float radius,
307 const SbColor& color,
308 float transparency)
309 {
310 return draw_cylinder((float)centerline_start.x(), (float)centerline_start.y(),
311 (float)centerline_start.z(), (float)centerline_end.x(),
312 (float)centerline_end.y(), (float)centerline_end.z(),
313 radius,
314 color,
315 transparency);
316 }
317
318
319 //:
320 // Important:
321 // Should use the draw_geometry to draw group of things for
322 // better performance.
323
draw_polyline(std::vector<vgl_point_3d<double>> & vertices,const float & width,const SbColor & color)324 SoSeparator* draw_polyline (std::vector<vgl_point_3d<double> >& vertices,
325 const float& width, const SbColor& color)
326 {
327 SoSeparator* root = new SoSeparator;
328
329 SoBaseColor *basecolor = new SoBaseColor;
330 basecolor->rgb = color;
331 root->addChild (basecolor);
332
333 // Line width
334 SoDrawStyle* drawStyle = new SoDrawStyle;
335 drawStyle->lineWidth.setValue (width);
336 root->addChild (drawStyle);
337
338 draw_polyline_geom (root, vertices);
339
340 return root;
341 }
342
draw_polyline_geom(SoGroup * root,std::vector<vgl_point_3d<double>> & vertices)343 void draw_polyline_geom (SoGroup *root, std::vector<vgl_point_3d<double> >& vertices)
344 {
345 unsigned int nVertices = vertices.size();
346 SbVec3f* verts = new SbVec3f[nVertices];
347
348 for (unsigned int i=0; i<nVertices; i++) {
349 vgl_point_3d<double> p = vertices[i];
350 verts[i] = SbVec3f( (float)p.x(), (float)p.y(), (float)p.z() );
351 }
352
353 SoCoordinate3* coords = new SoCoordinate3;
354 coords->point.setValues (0, nVertices, verts);
355 root->addChild (coords);
356
357 SoLineSet* lineSet = new SoLineSet;
358 lineSet->numVertices.set1Value (0, nVertices);
359 root->addChild (lineSet);
360
361 delete[] verts;
362 }
363
364 // draws a polyline with the specified color and drawstyle
draw_polyline(const float ** vertices,const unsigned int nVertices,const SbColor & color,const SoDrawStyle * drawStyle)365 SoSeparator* draw_polyline (const float** vertices, const unsigned int nVertices,
366 const SbColor& color, const SoDrawStyle* drawStyle)
367 {
368 SoSeparator* root = new SoSeparator;
369
370 SoBaseColor *basecolor = new SoBaseColor;
371 basecolor->rgb = color;
372 root->addChild (basecolor);
373
374 // Line width
375 root->addChild ((SoDrawStyle*) drawStyle); // casting away const !!!
376
377 SbVec3f* verts = new SbVec3f[nVertices];
378 for (unsigned int i=0; i<nVertices; i++)
379 verts[i] = SbVec3f( vertices[i][0], vertices[i][1], vertices[i][2] );
380
381 draw_polyline_geom (root, verts, nVertices);
382
383 delete[] verts;
384
385 return root;
386 }
387
388 // draws a single polyline with no special properties
draw_polyline_geom(SoGroup * root,SbVec3f * vertices,const unsigned int nVertices)389 void draw_polyline_geom (SoGroup* root, SbVec3f* vertices, const unsigned int nVertices)
390 {
391 SoCoordinate3* coords = new SoCoordinate3;
392 coords->point.setValues (0, nVertices, vertices);
393 root->addChild (coords);
394
395 SoLineSet* lineSet = new SoLineSet;
396 lineSet->numVertices.set1Value (0, nVertices);
397 root->addChild (lineSet);
398 }
399
400
draw_filled_polygon_geom_(SoGroup * root,const std::vector<bmsh3d_vertex * > & vertices)401 void draw_filled_polygon_geom_ (SoGroup* root, const std::vector<bmsh3d_vertex*>& vertices)
402 {
403 SbVec3f* verts = new SbVec3f[vertices.size()];
404 for (unsigned int i=0; i<vertices.size(); i++)
405 verts[i] = SbVec3f(float(vertices[i]->pt().x()), float(vertices[i]->pt().y()), float(vertices[i]->pt().z()));
406
407 draw_filled_polygon_geom_ (root, verts, vertices.size());
408
409 delete[] verts;
410 }
411
412 //:
413 // Ming: We have two options to draw the IndexedFaceSet.
414 // Option 1: make the emissiveColor the same as diffuseColor
415 // The sheet will look continuously.
416 // Option 2: make the emissiveColor half value of diffuseColor (color/2)
417 // to show individual sheet elements.
418 // draws a polygon with the specified color, drawstyle and transparency
419
draw_filled_polygon(SbVec3f * vertices,const unsigned int nVertices,const SbColor & color,const float fTransparency)420 SoSeparator* draw_filled_polygon (SbVec3f* vertices, const unsigned int nVertices,
421 const SbColor& color, const float fTransparency)
422 {
423 SoSeparator* root = new SoSeparator;
424
425 // Create a SoMaterial to draw color in detail.
426 SoMaterial *material = new SoMaterial;
427 material->diffuseColor.setValue (color);
428 material->emissiveColor.setValue(color/2);
429 material->transparency = fTransparency;
430 root->addChild (material);
431
432 draw_filled_polygon_geom_ (root, vertices, nVertices);
433
434 return root;
435 }
436
draw_filled_polygon(float ** vertices,const unsigned int nVertices,const SbColor & color,const float fTransparency)437 SoSeparator* draw_filled_polygon (float** vertices, const unsigned int nVertices,
438 const SbColor& color, const float fTransparency)
439 {
440 SoSeparator* root = new SoSeparator;
441
442 // Create a SoMaterial to draw color in detail.
443 SoMaterial *material = new SoMaterial;
444 material->diffuseColor.setValue (color);
445 material->emissiveColor.setValue(color/2);
446 material->transparency = fTransparency;
447 root->addChild (material);
448
449 SbVec3f* verts = new SbVec3f[nVertices];
450 for (unsigned int i=0; i<nVertices; i++)
451 verts[i] = SbVec3f (vertices[i][0], vertices[i][1], vertices[i][2]);
452
453 draw_filled_polygon_geom_ (root, verts, nVertices);
454
455 delete[] verts;
456 return root;
457 }
458
459 // draw a simple filled polygon with no special properties
draw_filled_polygon_geom_(SoGroup * root,SbVec3f * vertices,const unsigned int nVertices)460 void draw_filled_polygon_geom_ (SoGroup* root, SbVec3f* vertices, const unsigned int nVertices)
461 {
462 SoCoordinate3* coords = new SoCoordinate3;
463 coords->point.setValues (0, nVertices, vertices);
464 root->addChild (coords);
465
466 SoFaceSet* faceSet = new SoFaceSet;
467 faceSet->numVertices.set1Value (0, nVertices);
468 root->addChild (faceSet);
469 }
470
draw_line_set(const std::vector<std::pair<vgl_point_3d<double>,vgl_point_3d<double>>> & lines,const SbColor & color)471 SoSeparator* draw_line_set (const std::vector<std::pair<vgl_point_3d<double>, vgl_point_3d<double> > >& lines,
472 const SbColor& color)
473 {
474 SoSeparator* root = new SoSeparator;
475 // color
476 SoBaseColor* basecolor = new SoBaseColor;
477 basecolor->rgb = color;
478 root->addChild (basecolor);
479
480 draw_line_set_geom (root, lines);
481
482 return root;
483 }
484
485 //: draw the whole set of lines in a single SoIndexedLineSet.
draw_line_set_geom(SoSeparator * root,const std::vector<std::pair<vgl_point_3d<double>,vgl_point_3d<double>>> & lines)486 void draw_line_set_geom(SoSeparator* root,
487 const std::vector<std::pair<vgl_point_3d<double>, vgl_point_3d<double> > >& lines)
488 {
489 unsigned int nVertices = lines.size() * 2;
490 float (*xyz)[3] = new float[nVertices][3];
491 unsigned int nLinesIndices = lines.size() * 3; // sid : eid : -1
492 int* ind = new int [nLinesIndices];
493
494 // Assign vertices and lines
495 for (unsigned int i=0; i < lines.size(); i++) {
496 vgl_point_3d<double> Ps = lines[i].first;
497 vgl_point_3d<double> Pe = lines[i].second;
498 xyz[i*2][0] = (float) Ps.x();
499 xyz[i*2][1] = (float) Ps.y();
500 xyz[i*2][2] = (float) Ps.z();
501 xyz[i*2+1][0] = (float) Pe.x();
502 xyz[i*2+1][1] = (float) Pe.y();
503 xyz[i*2+1][2] = (float) Pe.z();
504 ind[i*3] = i*2;
505 ind[i*3+1] = i*2+1;
506 ind[i*3+2] = -1;
507 }
508
509 SoVertexProperty* vp = new SoVertexProperty;
510 vp->vertex.setValues (0, nVertices, xyz);
511
512 SoIndexedLineSet* indexedLineSet = new SoIndexedLineSet ();
513 indexedLineSet->vertexProperty = vp;
514 indexedLineSet->coordIndex.setValues (0, nLinesIndices, ind);
515
516 delete []ind;
517 delete []xyz;
518
519 root->addChild (indexedLineSet);
520 }
521
draw_triangle_geom(SoGroup * root,const vgl_point_3d<double> & Pt1,const vgl_point_3d<double> & Pt2,const vgl_point_3d<double> & Pt3)522 void draw_triangle_geom (SoGroup* root,
523 const vgl_point_3d<double>& Pt1,
524 const vgl_point_3d<double>& Pt2,
525 const vgl_point_3d<double>& Pt3)
526 {
527 SoCoordinate3* coords = new SoCoordinate3;
528 coords->point.set1Value( 0, SbVec3f( (float)Pt1.x(), (float)Pt1.y(), (float)Pt1.z()) );
529 coords->point.set1Value( 1, SbVec3f( (float)Pt2.x(), (float)Pt2.y(), (float)Pt2.z()) );
530 coords->point.set1Value( 2, SbVec3f( (float)Pt3.x(), (float)Pt3.y(), (float)Pt3.z()) );
531 root->addChild(coords);
532
533 SoFaceSet* faceSet = new SoFaceSet;
534 faceSet->numVertices.set1Value(0,3);
535 root->addChild(faceSet);
536 }
537
538 // draws a single triangle with no special properties
draw_triangle_geom(SoGroup * root,const float x1,const float y1,const float z1,const float x2,const float y2,const float z2,const float x3,const float y3,const float z3)539 void draw_triangle_geom (SoGroup *root,
540 const float x1, const float y1, const float z1,
541 const float x2, const float y2, const float z2,
542 const float x3, const float y3, const float z3)
543 {
544 SoCoordinate3* coords = new SoCoordinate3;
545 coords->point.set1Value(0,SbVec3f(x1,y1,z1));
546 coords->point.set1Value(1,SbVec3f(x2,y2,z2));
547 coords->point.set1Value(2,SbVec3f(x3,y3,z3));
548 root->addChild(coords);
549
550 SoFaceSet* faceSet = new SoFaceSet;
551 faceSet->numVertices.set1Value(0,3);
552 root->addChild(faceSet);
553 }
554
555 // draws a line with the specified color and drawstyle
draw_line(const float x1,const float y1,const float z1,const float x2,const float y2,const float z2,const SbColor & color,const SoDrawStyle * drawStyle)556 SoSeparator* draw_line (const float x1, const float y1, const float z1,
557 const float x2, const float y2, const float z2,
558 const SbColor& color, const SoDrawStyle* drawStyle)
559 {
560 SoSeparator* root = new SoSeparator;
561
562 // color
563 SoBaseColor *basecolor = new SoBaseColor;
564 basecolor->rgb = color;
565 root->addChild (basecolor);
566
567 if (drawStyle)
568 root->addChild ((SoDrawStyle*) drawStyle); // casting away const !!!
569
570 draw_line_geom (root, x1, y1, z1, x2, y2, z2);
571 return root;
572 }
573
574 // draws a line with the specified color and drawstyle
draw_line(const vgl_point_3d<double> & pt1,const vgl_point_3d<double> & pt2,const SbColor & color,const SoDrawStyle * drawStyle)575 SoSeparator* draw_line (const vgl_point_3d<double>& pt1, const vgl_point_3d<double>& pt2,
576 const SbColor& color, const SoDrawStyle* drawStyle)
577 {
578 return draw_line ((float)pt1.x(), (float)pt1.y(), (float)pt1.z(),
579 (float)pt2.x(), (float)pt2.y(), (float)pt2.z(), color, drawStyle);
580 }
581
582 // draws a single line with no special properties
draw_line_geom(SoGroup * root,const float x1,const float y1,const float z1,const float x2,const float y2,const float z2)583 void draw_line_geom (SoGroup* root,
584 const float x1, const float y1, const float z1,
585 const float x2, const float y2, const float z2)
586 {
587 SoCoordinate3* coord = new SoCoordinate3;
588 coord->point.set1Value(0, SbVec3f( x1,y1,z1 ) );
589 coord->point.set1Value(1, SbVec3f( x2,y2,z2 ) );
590 root->addChild( coord );
591
592 SoLineSet* lineSet = new SoLineSet;
593 lineSet->numVertices.set1Value( 0, 2 );
594 root->addChild( lineSet );
595 }
596
draw_line_geom(SoGroup * root,const vgl_point_3d<double> & pt1,const vgl_point_3d<double> & pt2)597 void draw_line_geom (SoGroup* root, const vgl_point_3d<double>& pt1, const vgl_point_3d<double>& pt2)
598 {
599 draw_line_geom (root,
600 (float)pt1.x(), (float)pt1.y(), (float)pt1.z(),
601 (float)pt2.x(), (float)pt2.y(), (float)pt2.z());
602 }
603
draw_text2d(const char * text,const float x,const float y,const float z)604 SoSeparator* draw_text2d (const char* text,
605 const float x, const float y, const float z)
606 {
607 SoSeparator* root = new SoSeparator;
608
609 SoTransform *instrTransf = new SoTransform;
610 instrTransf->translation.setValue (x, y, z);
611 root->addChild(instrTransf);
612
613 draw_text2d_geom (root, text);
614
615 return root;
616 }
617
draw_box(const double & min_x,const double & min_y,const double & min_z,const double & max_x,const double & max_y,const double & max_z,const float & width,const SbColor & color)618 SoSeparator* draw_box (const double& min_x, const double& min_y, const double& min_z,
619 const double& max_x, const double& max_y, const double& max_z,
620 const float& width, const SbColor& color)
621 {
622 SoSeparator* root = new SoSeparator;
623
624 // color
625 SoBaseColor* basecolor = new SoBaseColor;
626 basecolor->rgb = color;
627 root->addChild (basecolor);
628
629 SoDrawStyle* drawStyle = new SoDrawStyle;
630 drawStyle->lineWidth.setValue (width);
631 root->addChild (drawStyle);
632
633 // side parallel to X
634 draw_line_geom (root, (float)min_x, (float)min_y, (float)min_z, (float)max_x, (float)min_y, (float)min_z);
635 draw_line_geom (root, (float)min_x, (float)min_y, (float)max_z, (float)max_x, (float)min_y, (float)max_z);
636 draw_line_geom (root, (float)min_x, (float)max_y, (float)min_z, (float)max_x, (float)max_y, (float)min_z);
637 draw_line_geom (root, (float)min_x, (float)max_y, (float)max_z, (float)max_x, (float)max_y, (float)max_z);
638
639 // side parallel to Y
640 draw_line_geom (root, (float)min_x, (float)min_y, (float)min_z, (float)min_x, (float)max_y, (float)min_z);
641 draw_line_geom (root, (float)min_x, (float)min_y, (float)max_z, (float)min_x, (float)max_y, (float)max_z);
642 draw_line_geom (root, (float)max_x, (float)min_y, (float)min_z, (float)max_x, (float)max_y, (float)min_z);
643 draw_line_geom (root, (float)max_x, (float)min_y, (float)max_z, (float)max_x, (float)max_y, (float)max_z);
644
645 // side parallel to Z
646 draw_line_geom (root, (float)min_x, (float)min_y, (float)min_z, (float)min_x, (float)min_y, (float)max_z);
647 draw_line_geom (root, (float)min_x, (float)max_y, (float)min_z, (float)min_x, (float)max_y, (float)max_z);
648 draw_line_geom (root, (float)max_x, (float)min_y, (float)min_z, (float)max_x, (float)min_y, (float)max_z);
649 draw_line_geom (root, (float)max_x, (float)max_y, (float)min_z, (float)max_x, (float)max_y, (float)max_z);
650
651 return root;
652 }
653
draw_box(const vgl_box_3d<double> & box,const float & width,const SbColor & color)654 SoSeparator* draw_box (const vgl_box_3d<double>& box,
655 const float& width, const SbColor& color)
656 {
657 return draw_box (box.min_x(), box.min_y(), box.min_z(),
658 box.max_x(), box.max_y(), box.max_z(),
659 width, color);
660 }
661
draw_text2d(const char * text,const float x,const float y,const float z,const SoBaseColor * basecolor)662 SoSeparator* draw_text2d (const char* text,
663 const float x, const float y, const float z,
664 const SoBaseColor* basecolor)
665 {
666 SoSeparator* root = new SoSeparator;
667
668 SoTransform *instrTransf = new SoTransform;
669 instrTransf->translation.setValue (x, y, z);
670 root->addChild(instrTransf);
671
672 // basecolor
673 root->addChild ((SoBaseColor*) basecolor); // casting away const !!!
674
675 draw_text2d_geom (root, text);
676
677 return root;
678 }
679
draw_text2d_geom(SoSeparator * root,const char * text)680 void draw_text2d_geom (SoSeparator* root, const char* text)
681 {
682 SoText2 * text2 = new SoText2;
683 SbString txt = SbString (text);
684 text2->string.setValues (0, sizeof(text) / sizeof(char *), &txt);
685 text2->justification = SoText2::LEFT;
686 root->addChild(text2);
687 }
688
689 // ############################################################
690
691 vnl_random colrand;
692
init_rand_color(unsigned long seed)693 void init_rand_color (unsigned long seed)
694 {
695 colrand.reseed (seed);
696 }
697
get_next_rand_ccode()698 VIS_COLOR_CODE get_next_rand_ccode ()
699 {
700 double c = colrand.drand32 (1, COLOR_ORANGE);
701 return (VIS_COLOR_CODE) int (c);
702 }
703
get_next_rand_color()704 SbColor get_next_rand_color ()
705 {
706 float r = (float) colrand.drand32 (0, 1);
707 float g = (float) colrand.drand32 (0, 1);
708 float b = (float) colrand.drand32 (0, 1);
709
710 SbColor color = SbColor (r, g, b);
711
712 return color;
713 }
714
shift_output(SoSeparator * vis,float shift_x,float shift_y,float shift_z)715 SoSeparator* shift_output (SoSeparator* vis, float shift_x, float shift_y, float shift_z)
716 {
717 SoSeparator* trans_group = new SoSeparator;
718 SoTranslation *trans = new SoTranslation;
719 trans->translation.setValue (SbVec3f (shift_x, shift_y, shift_z));
720 trans_group->addChild (trans);
721 trans_group->addChild (vis);
722 return trans_group;
723 }
724
725 // ##################################################################
726
727 #if 0
728
729 void draw_point_test (SoSeparator* root)
730 {
731 constexpr int NUMPOINTS = 5000;
732 float xyz[NUMPOINTS][3];
733
734 for (int i=0; i < NUMPOINTS; i++) {
735 xyz[i][0] = (float)rand() / (float)RAND_MAX * 10;
736 xyz[i][1] = (float)rand() / (float)RAND_MAX * 10;
737 xyz[i][2] = (float)rand() / (float)RAND_MAX * 10;
738 }
739
740 SoCoordinate3 * coord3 = new SoCoordinate3;
741 coord3->point.setValues(0, NUMPOINTS, xyz);
742 root->addChild(coord3);
743
744 SoDrawStyle * drawstyle = new SoDrawStyle;
745 drawstyle->pointSize = 1;
746 root->addChild(drawstyle);
747
748 SoPointSet * pointset = new SoPointSet;
749 root->addChild(pointset);
750 }
751
752 void draw_text_test (SoSeparator* root)
753 {
754 SoText2 * text = new SoText2;
755
756 const char * str[] = {
757 "Yo Yo Yo. 2D Text is working!",
758 "LEMS Brown University",
759 "1 2 3 4 5 6 7 8 9 10.",
760 };
761
762 text->string.setValues(0, sizeof(str) / sizeof(char *), str);
763 text->justification = SoText2::LEFT;
764 SoTransform *instrTransf = new SoTransform;
765 instrTransf->translation.setValue(-1.0f,5.0f,0.0f);
766 root->addChild(instrTransf);
767 root->addChild(text);
768 }
769
770 void draw_polyline_test (SoSeparator* root)
771 {
772 // Points in N*3 float array.
773 SoVertexProperty *vertexList = new SoVertexProperty();
774 root->addChild(vertexList);
775
776 int N = 3;
777 #if 0
778 for (int i=0; i<N; i++)
779 vertexList->vertex.set1Value (i, 1.2*i, 1.3*i*i, 1.4*i);
780 #endif // 0
781 vertexList->vertex.set1Value (0, 0, 0, 0);
782 vertexList->vertex.set1Value (1, 1, 1, 1);
783 vertexList->vertex.set1Value (2, 5, 1, 1);
784
785 // Line
786 int N_LINE = N-1;
787 int *lineindex = new int[N_LINE*3];
788 for (int i=0; i<N_LINE; i++) {
789 lineindex[i*3] = i;
790 lineindex[i*3+1] = i+1;
791 lineindex[i*3+2] = -1;
792 }
793
794 SoIndexedLineSet *vertIndex = new SoIndexedLineSet();
795 vertIndex->coordIndex.setValues (0, N_LINE*3, lineindex);
796 root->addChild(vertIndex);
797
798 delete[] lineindex;
799 }
800
801 void draw_polygon_test (SoSeparator* root)
802 {
803 // Points in N*3 float array.
804 SoVertexProperty *vertexList = new SoVertexProperty();
805 root->addChild(vertexList);
806
807 int N = 3;
808 #if 0
809 for (int i=0; i<N; i++)
810 vertexList->vertex.set1Value (i, 1.2*i, 1.3*i*i, 1.4*i);
811 #endif // 0
812 vertexList->vertex.set1Value (0, 0, 0, 0);
813 vertexList->vertex.set1Value (1, 1, 1, 1);
814 vertexList->vertex.set1Value (2, 5, 1, 1);
815
816 // Line
817 int N_LINE = N;
818 int *lineindex = new int[N_LINE*3];
819 for (int i=0; i<N_LINE-1; i++) {
820 lineindex[i*3] = i;
821 lineindex[i*3+1] = i+1;
822 lineindex[i*3+2] = -1;
823 }
824 int i = N_LINE-1;
825 lineindex[i*3] = i;
826 lineindex[i*3+1] = 0;
827 lineindex[i*3+2] = -1;
828
829 SoIndexedLineSet *vertIndex = new SoIndexedLineSet();
830 vertIndex->coordIndex.setValues (0, N_LINE*3, lineindex);
831 root->addChild(vertIndex);
832
833 delete []lineindex;
834 }
835
836
837 void draw_filled_polygon_test (SoSeparator* root)
838 {
839 // Points in N*3 float array.
840 SoVertexProperty *vertexList = new SoVertexProperty();
841 root->addChild(vertexList);
842
843 int N = 3;
844 #if 0
845 for (int i=0; i<N; i++)
846 vertexList->vertex.set1Value (i, 1.2*i, 1.3*i*i, 1.4*i);
847 #endif // 0
848 vertexList->vertex.set1Value (0, 0, 0, 0);
849 vertexList->vertex.set1Value (1, 1, 1, 1);
850 vertexList->vertex.set1Value (2, 5, 1, 1);
851
852 // Face 1
853 int N_VERTICES = (N+1)*2;
854 int *faceindex = new int[N_VERTICES];
855 for (int i=0; i<N; i++)
856 faceindex[i] = i;
857 faceindex[N] = -1;
858
859 // Face 2
860 for (int i=0; i<N; i++)
861 faceindex[N+1+i] = N-1-i;
862 faceindex[N*2+1] = -1;
863
864 SoIndexedFaceSet *vertIndex = new SoIndexedFaceSet();
865 vertIndex->coordIndex.setValues (0, N_VERTICES, faceindex);
866 root->addChild(vertIndex);
867
868 SoShapeHints * hints = new SoShapeHints;
869 hints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
870 hints->shapeType = SoShapeHints::SOLID;
871 root->addChild(hints);
872
873 delete[] faceindex;
874 }
875
876 void draw_indexed_line_test (SoSeparator* root)
877 {
878 // Put a wireframe cube in the scene.
879 SoSeparator *cubeSep = new SoSeparator();
880
881 const SbVec3f CubeMin = SbVec3f(-1.0, -1.0, -1.0);
882 const SbVec3f CubeMax = SbVec3f( 1.0, 1.0, 1.0);
883
884 ////////////////////////////////////////////////////////////
885
886 //:
887 // \verbatim
888 // Create an array of points at the vertices of the cube.
889 //
890 // y
891 // ^
892 // 2 | 3
893 // .-----------|----------------.
894 // / | /|
895 // / | | / |
896 // / / |
897 // 7 / | 6 / |
898 // .----------------------------. |
899 // | | | |
900 // | | |
901 // | | | ------> x
902 // | | |
903 // | | | |
904 // | | |
905 // | | | |
906 // | .- - - - - - - - - - - -|- - .
907 // | 0 | / 1
908 // | / | /
909 // | | /
910 // |/ |/
911 // .----------------------------.
912 // 4 5
913 // \endverbatim
914
915 constexpr int numCubeVerts = 8;
916 static float cubeVerts[numCubeVerts][3] =
917 {
918 { CubeMin[0], CubeMin[1], CubeMax[2] }, // vert 0
919 { CubeMax[0], CubeMin[1], CubeMax[2] }, // vert 1
920 { CubeMin[0], CubeMax[1], CubeMax[2] }, // vert 2
921 { CubeMax[0], CubeMax[1], CubeMax[2] }, // vert 3
922
923 { CubeMin[0], CubeMin[1], CubeMin[2] }, // vert 4
924 { CubeMax[0], CubeMin[1], CubeMin[2] }, // vert 5
925 { CubeMin[0], CubeMax[1], CubeMin[2] }, // vert 6
926 { CubeMax[0], CubeMax[1], CubeMin[2] } // vert 7
927 };
928
929 ////////////////////////////////////////////////////////////
930 //
931 // Index into the array of vertices to create segments
932 // defining the edges of the cube.
933 //
934 // For example, 0, 1, -1 will designate a segment from
935 // cubeVerts[0] to cubeVerts[1].
936
937 SoVertexProperty *vertexList = new SoVertexProperty();
938 vertexList->vertex.setValues( 0, numCubeVerts, cubeVerts);
939 root->addChild(vertexList);
940
941 constexpr int numEdgeIndexes = 36;
942 static int32_t cubeIndex[numEdgeIndexes] =
943 {
944 0, 1, -1, // -1 terminates the edge.
945 2, 3, -1,
946 0, 2, -1,
947 1, 3, -1,
948
949 4, 5, -1,
950 6, 7, -1,
951 4, 6, -1,
952 5, 7, -1,
953
954 0, 4, -1,
955 1, 5, -1,
956 2, 6, -1,
957 3, 7, -1,
958 };
959
960 SoIndexedLineSet *vertIndex = new SoIndexedLineSet();
961 vertIndex->coordIndex.setValues(0, numEdgeIndexes, cubeIndex);
962 root->addChild(vertIndex);
963 root->addChild(cubeSep);
964 }
965
966 void draw_primitives_test (SoSeparator* root)
967 {
968 root->addChild (new SoCone);
969 root->addChild (new SoCylinder);
970 root->addChild (new SoSphere);
971 }
972
973 #endif
974