@@ -27,16 +27,21 @@ DEALINGS IN THE SOFTWARE.
2727*/
2828
2929#include < Modules/Visualization/InterfaceWithOspray.h>
30- // #include <Core/Datatypes/Geometry.h>
30+ #include < Core/Datatypes/Geometry.h>
3131// #include <Core/Algorithms/Visualization/RenderFieldState.h>
3232// #include <Core/Datatypes/Legacy/Field/VMesh.h>
3333// #include <Core/Datatypes/Legacy/Field/Field.h>
3434// #include <Core/Datatypes/Legacy/Field/VField.h>
3535// #include <Core/Datatypes/Color.h>
36- // #include <Core/Datatypes/ColorMap.h>
36+ #include < Core/Datatypes/ColorMap.h>
3737// #include <Core/GeometryPrimitives/Vector.h>
3838// #include <Core/GeometryPrimitives/Tensor.h>
3939// #include <Graphics/Glyphs/GlyphGeom.h>
40+ #include < Core/Datatypes/Legacy/Field/Field.h>
41+ #include < Core/Datatypes/Legacy/Field/VMesh.h>
42+ #include < Core/Datatypes/Mesh/VirtualMeshFacade.h>
43+
44+ #include < ospray/ospray.h>
4045
4146using namespace SCIRun ;
4247using namespace Modules ::Visualization;
@@ -192,18 +197,175 @@ void InterfaceWithOspray::setStateDefaults()
192197 // // is more up in the air.
193198}
194199
200+ namespace
201+ {
202+ class OsprayImpl
203+ {
204+ public:
205+ OsprayImpl ()
206+ {
207+ const char * argv[] = { " " };
208+ int argc = 0 ;
209+ int init_error = ospInit (&argc, argv);
210+ if (init_error != OSP_NO_ERROR)
211+ throw init_error;
212+ }
213+
214+ void writeImage (FieldHandle field, const std::string& filename, float cameraSteps)
215+ {
216+ auto facade (field->mesh ()->getFacade ());
217+
218+ std::cout << " hello ospray" << std::endl;
219+ // image size
220+ osp::vec2i imgSize;
221+ imgSize.x = 1024 ; // width
222+ imgSize.y = 768 ; // height
223+
224+ // camera
225+ float cam_pos[] = { -1 .f , 0 .f , -5 .f };
226+ cam_pos[0 ] += cameraSteps;
227+ float cam_up[] = { 0 .f , 1 .f , 0 .f };
228+ float cam_view[] = { 0 .5f , 0 .5f , 1 .f };
229+
230+ std::vector<float > vertex, color;
231+ // float maxColor = max;
232+ {
233+ for (const auto & node : facade->nodes ())
234+ {
235+ auto point = node.point ();
236+ vertex.push_back (static_cast <float >(point.x ()));
237+ vertex.push_back (static_cast <float >(point.y ()));
238+ vertex.push_back (static_cast <float >(point.z ()));
239+ vertex.push_back (0 );
240+ color.push_back (0 .8f );
241+ color.push_back (0 .5f );
242+ color.push_back (0 .5f );
243+ color.push_back (1 .0f );
244+ }
245+ }
246+
247+ std::vector<int32_t > index;
248+ {
249+ for (const auto & face : facade->faces ())
250+ {
251+ auto nodes = face.nodeIndices ();
252+ index.push_back (static_cast <int32_t >(nodes[0 ]));
253+ index.push_back (static_cast <int32_t >(nodes[1 ]));
254+ index.push_back (static_cast <int32_t >(nodes[2 ]));
255+ }
256+ }
257+
258+ // create and setup camera
259+ OSPCamera camera = ospNewCamera (" perspective" );
260+ ospSetf (camera, " aspect" , imgSize.x / (float )imgSize.y );
261+ ospSet3fv (camera, " pos" , cam_pos);
262+ ospSet3fv (camera, " dir" , cam_view);
263+ ospSet3fv (camera, " up" , cam_up);
264+ ospCommit (camera); // commit each object to indicate modifications are done
265+
266+ // create and setup model and mesh
267+ OSPGeometry mesh = ospNewGeometry (" triangles" );
268+ OSPData data = ospNewData (vertex.size () / 4 , OSP_FLOAT3A, &vertex[0 ]); // OSP_FLOAT3 format is also supported for vertex positions
269+ // OSPData data = ospNewData(4, OSP_FLOAT3A, vertex_example); // OSP_FLOAT3 format is also supported for vertex positions
270+ ospCommit (data);
271+ ospSetData (mesh, " vertex" , data);
272+
273+ data = ospNewData (vertex.size () / 4 , OSP_FLOAT4, &color[0 ]);
274+ // data = ospNewData(4, OSP_FLOAT4, color_example);
275+ ospCommit (data);
276+ ospSetData (mesh, " vertex.color" , data);
277+
278+ data = ospNewData (index.size () / 3 , OSP_INT3, &index[0 ]); // OSP_INT4 format is also supported for triangle indices
279+ // data = ospNewData(2, OSP_INT3, index_example); // OSP_INT4 format is also supported for triangle indices
280+ ospCommit (data);
281+ ospSetData (mesh, " index" , data);
282+
283+ ospCommit (mesh);
284+
285+ OSPModel world = ospNewModel ();
286+ ospAddGeometry (world, mesh);
287+ ospCommit (world);
288+
289+ // create renderer
290+ OSPRenderer renderer = ospNewRenderer (" scivis" ); // choose Scientific Visualization renderer
291+
292+ // create and setup light for Ambient Occlusion
293+ OSPLight light = ospNewLight (renderer, " ambient" );
294+ ospCommit (light);
295+ OSPData lights = ospNewData (1 , OSP_LIGHT, &light);
296+ ospCommit (lights);
297+
298+ // complete setup of renderer
299+ ospSet1i (renderer, " aoSamples" , 1 );
300+ ospSet1f (renderer, " bgColor" , 1 .0f ); // white, transparent
301+ ospSetObject (renderer, " model" , world);
302+ ospSetObject (renderer, " camera" , camera);
303+ ospSetObject (renderer, " lights" , lights);
304+ ospCommit (renderer);
305+
306+ // create and setup framebuffer
307+ OSPFrameBuffer framebuffer = ospNewFrameBuffer (imgSize, OSP_FB_SRGBA, OSP_FB_COLOR | /* OSP_FB_DEPTH |*/ OSP_FB_ACCUM);
308+ ospFrameBufferClear (framebuffer, OSP_FB_COLOR | OSP_FB_ACCUM);
309+
310+ // render one frame
311+ ospRenderFrame (framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM);
312+
313+ // access framebuffer and write its content as PPM file
314+ const uint32_t * fb = (uint32_t *)ospMapFrameBuffer (framebuffer, OSP_FB_COLOR);
315+ ospUnmapFrameBuffer (fb, framebuffer);
316+
317+ // render 10 more frames, which are accumulated to result in a better converged image
318+ for (int frames = 0 ; frames < 10 ; frames++)
319+ ospRenderFrame (framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM);
320+
321+ fb = (uint32_t *)ospMapFrameBuffer (framebuffer, OSP_FB_COLOR);
322+
323+ writePPM (filename.c_str (), imgSize, fb);
324+ ospUnmapFrameBuffer (fb, framebuffer);
325+ }
326+ private:
327+ void writePPM (const char *fileName, const osp::vec2i &size, const uint32_t *pixel)
328+ {
329+ FILE *file = fopen (fileName, " wb" );
330+ fprintf (file, " P6\n %i %i\n 255\n " , size.x , size.y );
331+ unsigned char *out = (unsigned char *)alloca (3 * size.x );
332+ for (int y = 0 ; y < size.y ; y++) {
333+ const unsigned char *in = (const unsigned char *)&pixel[(size.y - 1 - y)*size.x ];
334+ for (int x = 0 ; x < size.x ; x++) {
335+ out[3 * x + 0 ] = in[4 * x + 0 ];
336+ out[3 * x + 1 ] = in[4 * x + 1 ];
337+ out[3 * x + 2 ] = in[4 * x + 2 ];
338+ }
339+ fwrite (out, 3 * size.x , sizeof (char ), file);
340+ }
341+ fprintf (file, " \n " );
342+ fclose (file);
343+ std::cout << " wrote file " << fileName << std::endl;
344+ }
345+ };
346+ }
347+
348+
195349void InterfaceWithOspray::execute ()
196350{
197- // auto field = getRequiredInput(Field);
198- // auto colorMap = getOptionalInput(ColorMapObject);
199- //
200- // if (needToExecute())
201- // {
202- // updateAvailableRenderOptions(field);
203- // auto geom = builder_->buildGeometryObject(field, colorMap, *this, this);
204- // sendOutput(SceneGraph, geom);
205- // }
351+ auto field = getRequiredInput (Field);
352+ auto colorMap = getOptionalInput (ColorMapObject);
353+
354+ if (needToExecute ())
355+ {
356+ OsprayImpl impl;
357+ // for (int inc : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
358+ // {
359+ // osprayImpl::renderLatVol(latVol, inc*0.2, GetParam());
360+ // }
361+ impl.writeImage (field, " scirunOsprayOutput.ppm" , 0.2 );
362+
363+ // updateAvailableRenderOptions(field);
364+ // auto geom = builder_->buildGeometryObject(field, colorMap, *this, this);
365+ // sendOutput(SceneGraph, geom);
366+ }
206367}
368+
207369#if 0
208370RenderState GeometryBuilder::getNodeRenderState(
209371 boost::optional<boost::shared_ptr<ColorMap>> colorMap)
0 commit comments