@@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE.
3434#include < Core/Datatypes/Legacy/Field/Field.h>
3535#include < Core/Datatypes/Legacy/Field/FieldInformation.h>
3636#include < Core/Datatypes/Legacy/Field/VMesh.h>
37+ #include < Core/Datatypes/Legacy/Field/LatVolMesh.h>
3738#include < Core/Datatypes/Mesh/VirtualMeshFacade.h>
3839#include < Core/Algorithms/Base/AlgorithmVariableNames.h>
3940#include < Core/Algorithms/Base/AlgorithmPreconditions.h>
@@ -310,11 +311,160 @@ std::vector<int32_t> OsprayDataAlgorithm::sort_points(EdgeVector edges, std::vec
310311
311312}
312313
313- OsprayGeometryObjectHandle OsprayDataAlgorithm::addSurface (FieldHandle field, ColorMapHandle colorMap) const
314+ OsprayGeometryObjectHandle OsprayDataAlgorithm::addTriSurface (FieldHandle field, ColorMapHandle colorMap) const
314315{
315316 auto obj = fillDataBuffers (field, colorMap);
316317 obj->isSurface = true ;
317- obj->GeomType =" Surface" ;
318+ obj->GeomType =" TriSurface" ;
319+ return obj;
320+ }
321+
322+ OsprayGeometryObjectHandle OsprayDataAlgorithm::addQuadSurface (FieldHandle field, ColorMapHandle colorMap) const
323+ {
324+ auto obj = fillDataBuffers (field, colorMap);
325+ obj->isSurface = true ;
326+ obj->GeomType =" QuadSurface" ;
327+ return obj;
328+ }
329+
330+ OsprayGeometryObjectHandle OsprayDataAlgorithm::addStructVol (FieldHandle field, ColorMapHandle colorMap) const
331+ {
332+ auto obj = makeObject (field);
333+ obj->isVolume = true ;
334+ obj->GeomType =" structVol" ;
335+
336+ auto & fieldData = obj->data ;
337+
338+ std::vector<float > voxels;
339+ std::vector<float > vertex_new;
340+
341+ auto facade (field->mesh ()->getFacade ());
342+ auto vfield = field->vfield ();
343+ auto vmesh = field->vmesh ();
344+
345+ const BBox bbox = vmesh->get_bounding_box ();
346+ Vector size = bbox.diagonal ();
347+ Point center = bbox.center ();
348+ VMesh::dimension_type dim;
349+ vmesh->get_dimensions (dim);
350+ Vector dimensions_ = Vector (1.0 ,1.0 ,1.0 );
351+ for (size_t p=0 ;p<dim.size ();p++) dimensions_[p] = static_cast <double >(dim[p]);
352+
353+ fieldData.dim_x = dimensions_[0 ];
354+ fieldData.dim_y = dimensions_[1 ];
355+ fieldData.dim_z = dimensions_[2 ];
356+ fieldData.origin_x = center.x () - size.x ()/2.0 ;
357+ fieldData.origin_y = center.y () - size.y ()/2.0 ;
358+ fieldData.origin_z = center.z () - size.z ()/2.0 ;
359+ fieldData.spacing_x = size.x ()/dimensions_[0 ];
360+ fieldData.spacing_y = size.y ()/dimensions_[1 ];
361+ fieldData.spacing_z = size.z ()/dimensions_[2 ];
362+
363+ double value;
364+ // std::cout << "mname:" << field->mesh()->type_name << std::endl;
365+
366+ for (const auto & node : facade->nodes ())
367+ {
368+ auto point = node.point ();
369+ if (vfield->num_values () > 0 )
370+ {
371+ vfield->get_value (value, node.index ());
372+ voxels.push_back (value);
373+ }
374+ vertex_new.push_back (static_cast <float >(point.x ()));
375+ vertex_new.push_back (static_cast <float >(point.y ()));
376+ vertex_new.push_back (static_cast <float >(point.z ()));
377+
378+ }
379+ // auto alpha = static_cast<float>(get(Parameters::DefaultColorA).toDouble());
380+ if (colorMap)
381+ {
382+ ColorMap_OSP_helper cmp (colorMap->getColorMapName ());
383+ obj->tfn .colors = cmp.colorList ;
384+
385+ // set default opacity for now
386+ // alpha pushed twice for both upper and lower values
387+ auto alpha = static_cast <float >(get (Parameters::DefaultColorA).toDouble ());
388+ obj->tfn .opacities .push_back (alpha);
389+ obj->tfn .opacities .push_back (alpha);
390+ }
391+ fieldData.color = voxels;
392+ fieldData.vertex = vertex_new;
393+ return obj;
394+ }
395+
396+ OsprayGeometryObjectHandle OsprayDataAlgorithm::addUnstructVol (FieldHandle field, ColorMapHandle colorMap) const
397+ {
398+ auto obj = makeObject (field);
399+ obj->isVolume = true ;
400+ obj->GeomType =" unstructVol" ;
401+
402+ auto & fieldData = obj->data ;
403+
404+ std::vector<float > voxels;
405+ std::vector<float > vertex_new;
406+ std::vector<int32_t > index_new;
407+
408+ auto facade (field->mesh ()->getFacade ());
409+ auto vfield = field->vfield ();
410+ auto vmesh = field->vmesh ();
411+
412+
413+ double value;
414+ // std::cout << "mname:" << field->mesh()->type_name << std::endl;
415+ for (const auto & node : facade->nodes ())
416+ {
417+ auto point = node.point ();
418+ if (vfield->num_values () > 0 )
419+ {
420+ vfield->get_value (value, node.index ());
421+ voxels.push_back (value);
422+ }
423+ vertex_new.push_back (static_cast <float >(point.x ()));
424+ vertex_new.push_back (static_cast <float >(point.y ()));
425+ vertex_new.push_back (static_cast <float >(point.z ()));
426+ }
427+
428+ VMesh::Cell::iterator meshCellIter;
429+ VMesh::Cell::iterator meshCellEnd;
430+ vmesh->end (meshCellEnd);
431+
432+ int numVPerCell = -1 ;
433+ FieldInformation info (field);
434+
435+ if (info.is_tetvol ()) numVPerCell =4 ;
436+ else if (info.is_hexvol ()) numVPerCell =8 ;
437+ else THROW_ALGORITHM_INPUT_ERROR (" hex or tet only for unstructured volume!" );
438+
439+ for (vmesh->begin (meshCellIter); meshCellIter != meshCellEnd; ++meshCellIter)
440+ {
441+ // OSPRay require an index array of size 8
442+ // for each unstructured mesh cell
443+ // a tetrahedral cell's first 4 vertices are set to -1
444+ // a wedge cell's first 2 vertices are set to -2
445+ VMesh::Cell::index_type elemID = *meshCellIter;
446+ VMesh::Node::array_type nodesFromCell (8 );
447+ vmesh->get_nodes (nodesFromCell, elemID);
448+ for (int i=numVPerCell;i<8 ;i++)
449+ nodesFromCell[i] = -4 /(8 -numVPerCell);
450+ for (int i=numVPerCell;i<8 +numVPerCell;i++){
451+ index_new.push_back (nodesFromCell[i%8 ]);
452+ }
453+ }
454+ if (colorMap)
455+ {
456+ ColorMap_OSP_helper cmp (colorMap->getColorMapName ());
457+ obj->tfn .colors = cmp.colorList ;
458+
459+ // set default opacity for now
460+ // alpha pushed twice for both upper and lower values
461+ auto alpha = static_cast <float >(get (Parameters::DefaultColorA).toDouble ());
462+ obj->tfn .opacities .push_back (alpha);
463+ obj->tfn .opacities .push_back (alpha);
464+ }
465+ fieldData.color = voxels;
466+ fieldData.vertex = vertex_new;
467+ fieldData.index = index_new;
318468 return obj;
319469}
320470
@@ -421,19 +571,29 @@ OsprayGeometryObjectHandle OsprayDataAlgorithm::fillDataBuffers(FieldHandle fiel
421571 }
422572 }
423573
574+ FieldInformation info (field);
575+
576+
424577 auto & index = fieldData.index ;
425578 {
426579 for (const auto & face : facade->faces ())
427580 {
428581 auto nodes = face.nodeIndices ();
429- index.push_back (static_cast <int32_t >(nodes[0 ]));
430- index.push_back (static_cast <int32_t >(nodes[1 ]));
431- index.push_back (static_cast <int32_t >(nodes[2 ]));
582+ if (info.is_quadsurfmesh ()){
583+ // quad face added in reverse order for correct normal in OSPRay viewer
584+ index.push_back (static_cast <int32_t >(nodes[3 ]));
585+ index.push_back (static_cast <int32_t >(nodes[2 ]));
586+ index.push_back (static_cast <int32_t >(nodes[1 ]));
587+ index.push_back (static_cast <int32_t >(nodes[0 ]));
588+ }else {
589+ index.push_back (static_cast <int32_t >(nodes[0 ]));
590+ index.push_back (static_cast <int32_t >(nodes[1 ]));
591+ index.push_back (static_cast <int32_t >(nodes[2 ]));
592+ }
432593 }
433594 }
434595
435- FieldInformation info (field);
436- if (get (Parameters::UseNormals).toBool () && info.is_trisurfmesh ())
596+ if (get (Parameters::UseNormals).toBool () && info.is_surface ())
437597 {
438598 auto mesh = field->vmesh ();
439599 mesh->synchronize (Mesh::NORMALS_E);
@@ -471,7 +631,6 @@ AlgorithmOutput OsprayDataAlgorithm::run(const AlgorithmInput& input) const
471631 OsprayGeometryObjectHandle renderable;
472632
473633 FieldInformation info (field);
474-
475634 if (info.is_trisurfmesh ())
476635 {
477636 // currently only supports one output, so no point in doing both
@@ -481,7 +640,26 @@ AlgorithmOutput OsprayDataAlgorithm::run(const AlgorithmInput& input) const
481640 }
482641 else
483642 {
484- renderable = addSurface (field, colorMap);
643+ renderable = addTriSurface (field, colorMap);
644+ }
645+ }
646+ else if (info.is_quadsurfmesh ()){
647+ renderable = addQuadSurface (field, colorMap);
648+ // THROW_ALGORITHM_INPUT_ERROR("field type quad.");
649+ }
650+ else if (info.is_volume ())
651+ {
652+ if (info.is_hexvol ()){
653+ renderable = addUnstructVol (field, colorMap);
654+ // THROW_ALGORITHM_INPUT_ERROR("Hex vol not supported. LatVol only at this point");
655+ }else if (info.is_latvol ()){
656+ renderable = addStructVol (field, colorMap);
657+ // renderable = addStructVol(field, colorMap);
658+ }else if (info.is_tetvol ()){
659+ renderable = addUnstructVol (field, colorMap);
660+ // THROW_ALGORITHM_INPUT_ERROR("Tet vol not supported. LatVol only at this point");
661+ }else {
662+ THROW_ALGORITHM_INPUT_ERROR (" Unknown vol type. LatVol only at this point" );
485663 }
486664 }
487665 else if (info.is_pointcloudmesh ())
0 commit comments