Skip to content

Commit 699dd42

Browse files
author
Xuan Huang
committed
unstructured vol
1 parent 276b994 commit 699dd42

File tree

4 files changed

+182
-81
lines changed

4 files changed

+182
-81
lines changed

src/Core/Algorithms/Visualization/OsprayDataAlgorithm.cc

Lines changed: 106 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,11 @@ OsprayGeometryObjectHandle OsprayDataAlgorithm::addQuadSurface(FieldHandle field
327327
return obj;
328328
}
329329

330-
OsprayGeometryObjectHandle OsprayDataAlgorithm::addVol(FieldHandle field, ColorMapHandle colorMap) const
330+
OsprayGeometryObjectHandle OsprayDataAlgorithm::addStructVol(FieldHandle field, ColorMapHandle colorMap) const
331331
{
332332
auto obj = makeObject(field);
333333
obj->isVolume = true;
334-
obj->GeomType="Volume";
334+
obj->GeomType="structVol";
335335

336336
auto& fieldData = obj->data;
337337

@@ -340,21 +340,25 @@ OsprayGeometryObjectHandle OsprayDataAlgorithm::addVol(FieldHandle field, ColorM
340340

341341
auto facade(field->mesh()->getFacade());
342342
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]);
343352

344-
// //cast mesh to latvol and fill dim, space, origin
345-
//auto latVolM = (boost::shared_ptr<LatVolMesh<Core::Basis::HexTrilinearLgn<Core::Geometry::Point> > >) field->mesh();
346-
//std::vector<int> dim; latVolM->get_dim(dim);
347-
// std::vector<float> min; latVolM.get_min(min);
348-
/*fieldData.origin_x = latVolM->get_min_i();
349-
fieldData.origin_y = latVolM->get_min_j();
350-
fieldData.origin_z = latVolM->get_min_k();
351-
fieldData.dim_x = latVolM->get_ni();
352-
fieldData.dim_y = latVolM->get_nj();
353-
fieldData.dim_z = latVolM->get_nk();*/
354-
//get_ni
355-
fieldData.dim_x = 100; fieldData.dim_y = 100; fieldData.dim_z = 100;
356-
fieldData.origin_x = -1; fieldData.origin_y = -1; fieldData.origin_z = -1;
357-
fieldData.spacing_x = 0.02; fieldData.spacing_y = 0.02; fieldData.spacing_z = 0.02;
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];
358362

359363
double value;
360364
//std::cout << "mname:" << field->mesh()->type_name << std::endl;
@@ -372,15 +376,91 @@ OsprayGeometryObjectHandle OsprayDataAlgorithm::addVol(FieldHandle field, ColorM
372376
vertex_new.push_back(static_cast<float>(point.z()));
373377

374378
}
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+
// obj->tfn.opacities = cmp.opacityList;
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+
375412

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 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+
VMesh::Cell::index_type elemID = *meshCellIter;
442+
VMesh::Node::array_type nodesFromCell(8);
443+
vmesh->get_nodes(nodesFromCell, elemID);
444+
for(int i=numVPerCell;i<8;i++)
445+
nodesFromCell[i] = -4/(8-numVPerCell);
446+
for(int i=numVPerCell;i<16-numVPerCell;i++){
447+
index_new.push_back(nodesFromCell[i%8]);
448+
}
449+
}
376450
if (colorMap)
377451
{
378452
ColorMap_OSP_helper cmp(colorMap->getColorMapName());
379453
obj->tfn.colors = cmp.colorList;
380-
obj->tfn.opacities = cmp.opacityList;
454+
455+
// set default opacity for now
456+
// obj->tfn.opacities = cmp.opacityList;
457+
auto alpha = static_cast<float>(get(Parameters::DefaultColorA).toDouble());
458+
obj->tfn.opacities.push_back(alpha);
459+
obj->tfn.opacities.push_back(alpha);
381460
}
382461
fieldData.color = voxels;
383462
fieldData.vertex = vertex_new;
463+
fieldData.index = index_new;
384464
return obj;
385465
}
386466

@@ -546,7 +626,6 @@ AlgorithmOutput OsprayDataAlgorithm::run(const AlgorithmInput& input) const
546626
OsprayGeometryObjectHandle renderable;
547627

548628
FieldInformation info(field);
549-
550629
if (info.is_trisurfmesh())
551630
{
552631
// currently only supports one output, so no point in doing both
@@ -565,13 +644,16 @@ AlgorithmOutput OsprayDataAlgorithm::run(const AlgorithmInput& input) const
565644
}
566645
else if (info.is_volume())
567646
{
568-
if(info.is_latvol()){
569-
renderable = addVol(field, colorMap);
570-
}else if(info.is_tetvol()){
571-
THROW_ALGORITHM_INPUT_ERROR("Tet vol not supported. LatVol only at this point");
572-
}else if(info.is_hexvol()){
647+
if(info.is_hexvol()){
648+
//renderable = addUnstructVol(field, colorMap);
573649
THROW_ALGORITHM_INPUT_ERROR("Hex vol not supported. LatVol only at this point");
574-
}else{
650+
}else if(info.is_latvol()){
651+
renderable = addStructVol(field, colorMap);
652+
//renderable = addStructVol(field, colorMap);
653+
}else if(info.is_tetvol()){
654+
renderable = addUnstructVol(field, colorMap);
655+
//THROW_ALGORITHM_INPUT_ERROR("Tet vol not supported. LatVol only at this point");
656+
}else {
575657
THROW_ALGORITHM_INPUT_ERROR("Unknown vol type. LatVol only at this point");
576658
}
577659
}

src/Core/Algorithms/Visualization/OsprayDataAlgorithm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ namespace SCIRun
6868
Core::Datatypes::OsprayGeometryObjectHandle addSphere(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
6969
Core::Datatypes::OsprayGeometryObjectHandle addTriSurface(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
7070
Core::Datatypes::OsprayGeometryObjectHandle addQuadSurface(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
71-
Core::Datatypes::OsprayGeometryObjectHandle addVol(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
71+
Core::Datatypes::OsprayGeometryObjectHandle addStructVol(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
72+
Core::Datatypes::OsprayGeometryObjectHandle addUnstructVol(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
7273
Core::Datatypes::OsprayGeometryObjectHandle addCylinder(FieldHandle field, Core::Datatypes::ColorMapHandle colorMap) const;
7374
void connected_component_edges(EdgeVector all_edges, std::vector<EdgeVector>& subsets, std::vector<int>& size_regions)const;
7475
void ReorderNodes(std::vector<int32_t> index, std::vector<int32_t> cc_index, std::vector<float> vertex, std::vector<float> color, std::vector<int32_t>& index_new, std::vector<float>& vertex_new,std::vector<float>& color_new) const;

src/Interface/Modules/Render/Ospray/VolumeViewer.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -766,32 +766,10 @@ void VolumeViewer::loadVolume(OSPVolume vol, const vec2f& voxelRange, const box3
766766
// modelStates_.push_back(ModelState(ospNewModel()));
767767

768768
assert(vol);
769-
/*std::vector<float> colors;
770-
std::vector<float> opacities;
771-
colors.push_back(1);
772-
colors.push_back(0);
773-
colors.push_back(0);
774-
colors.push_back(0);
775-
colors.push_back(0);
776-
colors.push_back(1);
777-
opacities.push_back(0.5);
778-
opacities.push_back(0.5);
779-
OSPData cData = ospNewData(colors.size(), OSP_FLOAT3, colors.data());
780-
OSPData oData = ospNewData(opacities.size(), OSP_FLOAT, opacities.data());
781769

782-
ospSetData(transferFunction, "colors", cData);
783-
ospSetData(transferFunction, "opacities", oData);
784-
785-
// the transfer function will apply over this volume value range
786-
ospSet2f(transferFunction, "valueRange", 0, 1);
787-
ospCommit(transferFunction);
788-
// For now we set the same transfer function on all volumes.
789-
ospSetObject(vol, "transferFunction", transferFunction);*/
790770
ospCommit(vol);
791-
792771
// Add the loaded volume(s) to the model.
793772
ospAddVolume(modelStates_.back().model, vol);
794-
//std::cout<<"load volume "<<(int)vol<<std::endl;
795773
assert(!bounds.empty());
796774
// Add to volumes vector for the current model.
797775
modelStates_.back().volumes.push_back(std::make_shared<ModelState::Volume>(vol, bounds, voxelRange));

src/Interface/Modules/Render/OsprayViewerDialog.cc

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -225,47 +225,84 @@ namespace
225225
const auto& radius = obj->radius;
226226
const auto& geom_type = obj->GeomType;
227227

228-
SCIRun::LOG_DEBUG("adding Volume");
229-
OSPVolume vol = ospNewVolume("shared_structured_volume");
230-
231-
//bounds = ospcommon::box3f(ospcommon::vec3f(0.f), 1);
232-
233-
int numVoxels = obj->data.color.size();
234-
OSPData voxelData = ospNewData(numVoxels, OSP_FLOAT, obj->data.color.data());
235-
ospSetObject(vol, "voxelData", voxelData);
236-
//ospRelease(voxelData);
237-
SCIRun::LOG_DEBUG(std::to_string(numVoxels));
238-
239-
ospSetString(vol, "voxelType", "float");
240-
ospSet3i(vol, "dimensions", obj->data.dim_x, obj->data.dim_y, obj->data.dim_z);
241-
ospSet3f(vol, "gridSpacing", fieldData.spacing_x, fieldData.spacing_y, fieldData.spacing_z);
242-
ospSet3f(vol, "gridOrigin", fieldData.origin_x, fieldData.origin_y, fieldData.origin_z);
243-
244-
std::for_each(obj->data.color.begin(), obj->data.color.end(), [&](float &v) {
245-
if (!std::isnan(v))
246-
voxelRange.extend(v);
247-
//SCIRun::LOG_DEBUG(std::to_string(v));
248-
});
249-
for(int i=0;i<vertex.size();i+=3){
250-
ospcommon::vec3f v = ospcommon::vec3f(vertex[i], vertex[i+1], vertex[i+2]);
251-
bounds.extend(v);
252-
}
253228
const auto& func = obj->tfn;
254229
OSPTransferFunction transferFunction = ospNewTransferFunction("piecewise_linear");
255-
256-
257230
OSPData cData = ospNewData(func.colors.size()/3, OSP_FLOAT3, func.colors.data());
258231
OSPData oData = ospNewData(func.opacities.size(), OSP_FLOAT, func.opacities.data());
259232

260233
ospSetData(transferFunction, "colors", cData);
261234
ospSetData(transferFunction, "opacities", oData);
262-
ospSet2f(transferFunction, "valueRange", voxelRange.lower, voxelRange.upper);
263-
ospCommit(transferFunction);
264-
ospSetObject(vol, "transferFunction", transferFunction);
265-
return vol;
235+
236+
if (boost::iequals(geom_type, "structVol"))
237+
{
238+
239+
SCIRun::LOG_DEBUG("adding Volume");
240+
OSPVolume vol = ospNewVolume("shared_structured_volume");
241+
242+
int numVoxels = obj->data.color.size();
243+
OSPData voxelData = ospNewData(numVoxels, OSP_FLOAT, obj->data.color.data());
244+
ospSetObject(vol, "voxelData", voxelData);
245+
ospRelease(voxelData);
246+
SCIRun::LOG_DEBUG(std::to_string(numVoxels));
247+
248+
ospSetString(vol, "voxelType", "float");
249+
ospSet3i(vol, "dimensions", obj->data.dim_x, obj->data.dim_y, obj->data.dim_z);
250+
ospSet3f(vol, "gridSpacing", fieldData.spacing_x, fieldData.spacing_y, fieldData.spacing_z);
251+
ospSet3f(vol, "gridOrigin", fieldData.origin_x, fieldData.origin_y, fieldData.origin_z);
252+
253+
std::for_each(obj->data.color.begin(), obj->data.color.end(), [&](float &v) {
254+
if (!std::isnan(v))
255+
voxelRange.extend(v);
256+
//SCIRun::LOG_DEBUG(std::to_string(v));
257+
});
258+
for(int i=0;i<vertex.size();i+=3){
259+
ospcommon::vec3f v = ospcommon::vec3f(vertex[i], vertex[i+1], vertex[i+2]);
260+
bounds.extend(v);
261+
}
262+
263+
ospSet2f(transferFunction, "valueRange", voxelRange.lower, voxelRange.upper);
264+
ospCommit(transferFunction);
265+
ospSetObject(vol, "transferFunction", transferFunction);
266+
ospRelease(transferFunction);
267+
return vol;
268+
}else if (boost::iequals(geom_type, "unstructVol")){
269+
SCIRun::LOG_DEBUG("adding unstructured Volume");
270+
OSPVolume vol = ospNewVolume("unstructured_volume");
271+
272+
//int numVoxels = obj->data.color.size();
273+
OSPData vertexData = ospNewData(vertex.size()/3, OSP_FLOAT3, vertex.data());
274+
OSPData fieldsData = ospNewData(color.size(), OSP_FLOAT, color.data());
275+
OSPData indicesData = ospNewData(index.size()/4, OSP_INT4, index.data());
276+
277+
278+
ospSetObject(vol, "vertices", vertexData);
279+
ospSetData(vol, "field", fieldsData);
280+
ospSetData(vol, "indices", indicesData);
281+
282+
283+
ospRelease(vertexData);
284+
ospRelease(fieldsData);
285+
ospRelease(indicesData);
286+
287+
std::for_each(obj->data.color.begin(), obj->data.color.end(), [&](float &v) {
288+
if (!std::isnan(v))
289+
voxelRange.extend(v);
290+
});
291+
for(int i=0;i<vertex.size();i+=3){
292+
ospcommon::vec3f v = ospcommon::vec3f(vertex[i], vertex[i+1], vertex[i+2]);
293+
bounds.extend(v);
294+
}
295+
296+
ospSet2f(transferFunction, "valueRange", voxelRange.lower, voxelRange.upper);
297+
ospCommit(transferFunction);
298+
ospSetObject(vol, "transferFunction", transferFunction);
299+
ospRelease(transferFunction);
300+
return vol;
301+
302+
}
266303

267304
}
268-
305+
269306
ospcommon::box3f toOsprayBox(const BBox& box)
270307
{
271308
auto min = box.get_min();
@@ -431,7 +468,7 @@ void OsprayViewerDialog::createViewer(const CompositeOsprayGeometryObject& geom)
431468
std::vector<ospcommon::box3f> bounds_list;
432469

433470
for (const auto& obj : geom.objects()){
434-
if(boost::iequals(obj->GeomType, "Volume")){
471+
if((boost::iequals(obj->GeomType, "structVol"))||(boost::iequals(obj->GeomType, "unstructVol")) ) {
435472
ospcommon::range1f r;
436473
ospcommon::box3f b;
437474
vol_list.push_back(duplicatedCodeFromAlgorithm_vol(obj, r, b));
@@ -441,8 +478,11 @@ void OsprayViewerDialog::createViewer(const CompositeOsprayGeometryObject& geom)
441478
impl_->geoms_.push_back(duplicatedCodeFromAlgorithm(obj));
442479
}
443480
viewer_ = new VolumeViewer(params, guiParams, { impl_->geoms_, toOsprayBox(geom.box) }, this);
444-
481+
482+
445483
setupViewer(viewer_);
484+
485+
SCIRun::LOG_DEBUG("num of vol: "+std::to_string(vol_list.size()));
446486
// load volume here
447487
for(int i=0;i<vol_list.size();i++){
448488
viewer_->loadVolume(vol_list[i], voxelRange_list[i].toVec2f(), bounds_list[i]);

0 commit comments

Comments
 (0)