void SoOrthoSlice::rayPick(SoRayPickAction * action) { if (!this->shouldRayPick(action)) return; SoState * state = action->getState(); if (!PRIVATE(this)->confirmValidInContext(state)) { return; } const CvrVoxelBlockElement * vbelem = CvrVoxelBlockElement::getInstance(state); if (vbelem == NULL) { return; } this->computeObjectSpaceRay(action); const SbLine & ray = action->getLine(); const SbPlane sliceplane = PRIVATE(this)->getSliceAsPlane(action); SbVec3f intersection; if (sliceplane.intersect(ray, intersection) && // returns FALSE if parallel action->isBetweenPlanes(intersection)) { SbVec3s ijk = vbelem->objectCoordsToIJK(intersection); const SbVec3s & voxcubedims = vbelem->getVoxelCubeDimensions(); const SbBox3s voxcubebounds(SbVec3s(0, 0, 0), voxcubedims - SbVec3s(1, 1, 1)); if (voxcubebounds.intersect(ijk)) { SoPickedPoint * pp = action->addIntersection(intersection); // if NULL, something else is obstructing the view to the // volume, the app programmer only want the nearest, and we // don't need to continue our intersection tests if (pp == NULL) return; pp->setObjectNormal(sliceplane.getNormal()); SoOrthoSliceDetail * detail = new SoOrthoSliceDetail; pp->setDetail(detail, this); detail->objectcoords = intersection; detail->ijkcoords = ijk; detail->voxelvalue = vbelem->getVoxelValue(ijk); if (CvrUtil::useFlippedYAxis()) { static SbBool flag = FALSE; if (!flag) { SoDebugError::postWarning("SoOrthoSlice::rayPick", "RayPick'ing will not be correct for SoOrthoSlice when the " "obsolete CVR_USE_FLIPPED_Y_AXIS envvar is active."); flag = TRUE; } } } } // Common clipping plane handling. SoOrthoSlice::doAction(action); }
/*! Sets the current texture. Id \a didapply is TRUE, it is assumed that the texture image already is the current GL texture. Do not use this feature unless you know what you're doing. */ void SoGLMultiTextureImageElement::set(SoState * const state, SoNode * const node, const int unit, SoGLImage * image, Model model, const SbColor & blendColor) { SoGLMultiTextureImageElement * elem = (SoGLMultiTextureImageElement*) state->getElement(classStackIndex); PRIVATE(elem)->ensureCapacity(unit); GLUnitData & ud = PRIVATE(elem)->unitdata[unit]; // FIXME: buggy. Find some solution to handle this. pederb, 2003-11-12 // if (ud.glimage && ud.glimage->getImage()) ud.glimage->getImage()->readUnlock(); if (image) { // keep SoMultiTextureImageElement "up-to-date" inherited::set(state, node, unit, SbVec3s(0,0,0), 0, NULL, multi_translateWrap(image->getWrapS()), multi_translateWrap(image->getWrapT()), multi_translateWrap(image->getWrapR()), model, blendColor); ud.glimage = image; // make sure image isn't changed while this is the active texture // FIXME: buggy. Find some solution to handle this. pederb, 2003-11-12 // if (image->getImage()) image->getImage()->readLock(); } else { ud.glimage = NULL; inherited::setDefault(state, node, unit); } elem->updateGL(unit); // FIXME: check if it's possible to support for other units as well if ((unit == 0) && image && image->isOfType(SoGLBigImage::getClassTypeId())) { SoShapeStyleElement::setBigImageEnabled(state, TRUE); } SoShapeStyleElement::setTransparentTexture(state, SoGLMultiTextureImageElement::hasTransparency(state)); SoGLShaderProgram * prog = SoGLShaderProgramElement::get(state); if (prog) { SbString str; str.sprintf("coin_texunit%d_model", unit); prog->updateCoinParameter(state, SbName(str.getString()), ud.glimage ? model : 0); } }
void Oinv_cgrid::init( const Geostat_grid* grid ) { geostat_grid_ = grid; grid_ = dynamic_cast<const Cartesian_grid*>( grid ); SbVec3s dim = SbVec3s( grid_->nx(), grid_->ny(), grid_->nz() ); voxel_data_ = new uint8_t[ grid_->size() ]; initialized_ = false; painted_switch_ = new SoSwitch; oinv_node_->addChild( painted_switch_ ); // display the bounding box if no property is painted GsTLCoordVector cell_dims = grid_->cell_dimensions(); GsTLPoint origin = grid_->origin(); OinvBBox* bbox = new OinvBBox( origin.x()-cell_dims.x()/2, origin.y()-cell_dims.y()/2, origin.z()-cell_dims.z()/2, float(grid_->nx())*cell_dims.x(), float(grid_->ny())*cell_dims.y(), float(grid_->nz())*cell_dims.z() ); painted_switch_->addChild( bbox->oinv_node() ); /* When a property is painted, we can show: * 1- the bounding box * 2- the outer planes of the volume ("full volume") * 3- volume rendering * 4- slices * Options (2) and (3) are mutually exclusive. * All these options are contained inside the same separator, * called 'painted_main_separator' */ SoSeparator* painted_main_separator = new SoSeparator; painted_switch_->addChild( painted_main_separator ); //------------------------- // bounding box node bbox_switch_ = new GsTL_SoNode; painted_main_separator->addChild( bbox_switch_ ); bbox_switch_->addChild( bbox->oinv_node() ); bbox_switch_->visible = false; display_switch_ = new SoSwitch; painted_main_separator->addChild( display_switch_ ); //------------------------- // Volume rendering node SoSeparator * vol_rendering_and_slices_root = new SoSeparator; display_switch_->addChild( vol_rendering_and_slices_root ); SoSeparator * vol_rendering_root = new SoSeparator; vol_rendering_and_slices_root->addChild( vol_rendering_root ); clipplane_switch_ = new SoSwitch; vol_rendering_root->addChild( clipplane_switch_ ); setup_clipplanes(); /* SbBox3f vol_size( origin.x(), origin.y(), origin.z(), origin.x()+float(grid_->nx())*cell_dims.x(), origin.y()+float(grid_->ny())*cell_dims.y(), origin.z()+float(grid_->nz())*cell_dims.z() ); */ SbBox3f vol_size( origin.x()-cell_dims.x()/2, origin.y()-cell_dims.y()/2, origin.z()-cell_dims.z()/2, origin.x()-cell_dims.x()/2+float(grid_->nx())*cell_dims.x(), origin.y()-cell_dims.y()/2+float(grid_->ny())*cell_dims.y(), origin.z()-cell_dims.z()/2+float(grid_->nz())*cell_dims.z() ); // Add SoVolumeData to scene graph volume_data_ = new SoVolumeData(); volume_data_->setVolumeData(dim, voxel_data_, SoVolumeData::UNSIGNED_BYTE); volume_data_->setVolumeSize( vol_size ); vol_rendering_root->addChild(volume_data_); // Add TransferFunction (color map) to scene graph volrend_colormap_ = new SoTransferFunction(); volrend_colormap_->predefColorMap.setValue(SoTransferFunction::NONE); volrend_colormap_->colorMapType.setValue(SoTransferFunction::RGBA); vol_rendering_root->addChild( volrend_colormap_ ); // Add VolumeRender to scene graph rendering_switch_ = new SoSwitch; SoVolumeRender * volrend = new SoVolumeRender(); volrend->interpolation = SoVolumeRender::NEAREST; if( requires_manual_override( float(grid_->nx())*cell_dims.x(), float(grid_->ny())*cell_dims.y(), float(grid_->nz())*cell_dims.z() ) ) { volrend->numSlicesControl.setValue(SoVolumeRender::MANUAL); int num_slices = int( float(grid_->nx())*cell_dims.x() ); num_slices += int( float(grid_->ny())*cell_dims.y() ); num_slices += int( float(grid_->nz())*cell_dims.z() ); volrend->numSlices.setValue(num_slices); } rendering_switch_->addChild(volrend); rendering_switch_->whichChild = 0; vol_rendering_root->addChild(rendering_switch_); //------------------------- // Slices SoSeparator * slices_root = new SoSeparator; vol_rendering_and_slices_root->addChild( slices_root ); slices_node_ = new SoGroup; slices_root->addChild( slices_node_ ); //------------------------- // Full volume node SoSeparator * full_vol_root = new SoSeparator; display_switch_->addChild( full_vol_root ); full_volume_ = new Full_volume( grid_->nx(), grid_->ny(), grid_->nz(), voxel_data_, &initialized_, cmap_, cell_dims.x(), cell_dims.y(), cell_dims.z(), origin.x(), origin.y(), origin.z() ); full_vol_root->addChild( full_volume_->oinv_node() ); //------------------------- display_switch_->whichChild = 1; //painted_switch_->whichChild = 0; property_display_mode( Oinv::NOT_PAINTED ); }
void Texture3D(SoSeparator * root) { SoDB::createGlobalField("globalVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("globalTVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("globalnv", SoMFInt32::getClassTypeId()); SoDB::createGlobalField("planeVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("planeTVerts", SoMFVec3f::getClassTypeId()); doClipping(SbVec3f(0,0,0), SbRotation()); // SoSeparator * root = new SoSeparator; // root->ref(); SoComplexity * comp = new SoComplexity; comp->textureQuality.setValue((float)0.9); root->addChild(comp); SoTexture3 * texture = new SoTexture3; texture->wrapR.setValue(SoTexture3::CLAMP); texture->wrapS.setValue(SoTexture3::CLAMP); texture->wrapT.setValue(SoTexture3::CLAMP); // SbString filenames[64]; // for (int i=0;i<64;i++) // filenames[i].sprintf("../../../data/pgmvol/slice%02d.raw.pgm",i); // texture->filenames.setValues(0,64,filenames); unsigned char * img = generateTexture(256,256,256); texture->images.setValue(SbVec3s(256,256,256), 1, img); root->addChild(texture); SoMaterial * mat = new SoMaterial; mat->emissiveColor.setValue(1,1,1); root->addChild(mat); SoTransformerDragger * dragger = new SoTransformerDragger; dragger->scaleFactor.setValue(5,5,5); dragger->addValueChangedCallback(draggerCB, NULL); root->addChild(dragger); SoCoordinate3 * clippedCoords = new SoCoordinate3; clippedCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("globalVerts")); root->addChild(clippedCoords); SoTextureCoordinate3 * clippedTCoords = new SoTextureCoordinate3; clippedTCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("globalTVerts")); root->addChild(clippedTCoords); SoFaceSet * clippedFS = new SoFaceSet; clippedFS->numVertices.connectFrom((SoMFInt32 *) SoDB::getGlobalField("globalnv")); root->addChild(clippedFS); SoCoordinate3 * planeCoords = new SoCoordinate3; planeCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("planeVerts")); root->addChild(planeCoords); SoTextureCoordinate3 * planeTCoords = new SoTextureCoordinate3; planeTCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("planeTVerts")); root->addChild(planeTCoords); SoFaceSet * planeFS = new SoFaceSet; root->addChild(planeFS); }