// doc in super void SoOrthoSlice::computeBBox(SoAction * action, SbBox3f & box, SbVec3f & center) { SoState * state = action->getState(); if (!PRIVATE(this)->confirmValidInContext(state)) { return; } const CvrVoxelBlockElement * vbelem = CvrVoxelBlockElement::getInstance(state); if (vbelem == NULL) return; SbBox3f vdbox = vbelem->getUnitDimensionsBox(); SbVec3f bmin, bmax; vdbox.getBounds(bmin, bmax); const SbVec3s & dimensions = vbelem->getVoxelCubeDimensions(); const int axisidx = (int)axis.getValue(); const int slice = this->sliceNumber.getValue(); const float depth = (float)fabs(bmax[axisidx] - bmin[axisidx]); bmin[axisidx] = bmax[axisidx] = (bmin[axisidx] + (depth / dimensions[axisidx]) * slice); vdbox.setBounds(bmin, bmax); box.extendBy(vdbox); center = vdbox.getCenter(); }
// Render 3D box. // // FIXME: should make bbox debug rendering part of SoSeparator / // SoGroup. 20030305 mortene. void SoOrthoSliceP::renderBox(SoGLRenderAction * action, SbBox3f box) { SbVec3f bmin, bmax; box.getBounds(bmin, bmax); glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glColor4ub(0xff, 0xff, 0xff, 0xff); glLineStipple(1, 0xffff); glLineWidth(2); glBegin(GL_LINES); glVertex3f(bmin[0], bmin[1], bmin[2]); glVertex3f(bmin[0], bmin[1], bmax[2]); glVertex3f(bmax[0], bmin[1], bmin[2]); glVertex3f(bmax[0], bmin[1], bmax[2]); glVertex3f(bmax[0], bmax[1], bmin[2]); glVertex3f(bmax[0], bmax[1], bmax[2]); glVertex3f(bmin[0], bmax[1], bmin[2]); glVertex3f(bmin[0], bmax[1], bmax[2]); glVertex3f(bmin[0], bmin[1], bmin[2]); glVertex3f(bmax[0], bmin[1], bmin[2]); glVertex3f(bmin[0], bmin[1], bmax[2]); glVertex3f(bmax[0], bmin[1], bmax[2]); glVertex3f(bmin[0], bmax[1], bmax[2]); glVertex3f(bmax[0], bmax[1], bmax[2]); glVertex3f(bmin[0], bmax[1], bmin[2]); glVertex3f(bmax[0], bmax[1], bmin[2]); glVertex3f(bmin[0], bmin[1], bmin[2]); glVertex3f(bmin[0], bmax[1], bmin[2]); glVertex3f(bmin[0], bmin[1], bmax[2]); glVertex3f(bmin[0], bmax[1], bmax[2]); glVertex3f(bmax[0], bmin[1], bmax[2]); glVertex3f(bmax[0], bmax[1], bmax[2]); glVertex3f(bmax[0], bmin[1], bmin[2]); glVertex3f(bmax[0], bmax[1], bmin[2]); glEnd(); glPopAttrib(); }
void IvDragger::_GetBounds(SoSeparator *subtree, AABB& ab) { SoGetBoundingBoxAction bbox(_viewer.lock()->GetViewer()->getViewportRegion()); bbox.apply(subtree); SbBox3f box = bbox.getBoundingBox(); RaveVector<float> vmin, vmax; box.getBounds(vmin.x,vmin.y,vmin.z,vmax.x,vmax.y,vmax.z); ab.pos = 0.5*(vmin+vmax); ab.extents = 0.5*(vmax-vmin); }
/** * Renders the label. */ void SoTextLabel::GLRender(SoGLRenderAction *action) { if (!this->shouldGLRender(action)) return; // only draw text without background if (!this->background.getValue()) { inherited::GLRender(action); return; } SoState * state = action->getState(); state->push(); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); SbBox3f box; SbVec3f center; this->computeBBox(action, box, center); if (!SoCullElement::cullTest(state, box, TRUE)) { SoMaterialBundle mb(action); mb.sendFirst(); const SbMatrix & mat = SoModelMatrixElement::get(state); //const SbViewVolume & vv = SoViewVolumeElement::get(state); const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) * SoProjectionMatrixElement::get(state)); const SbViewportRegion & vp = SoViewportRegionElement::get(state); SbVec2s vpsize = vp.getViewportSizePixels(); // font stuff //float space = this->spacing.getValue(); //float fontsize = SoFontSizeElement::get(state); SbName fontname = SoFontNameElement::get(state); int lines = this->string.getNum(); // get left bottom corner of the label SbVec3f nilpoint(0.0f, 0.0f, 0.0f); projmatrix.multVecMatrix(nilpoint, nilpoint); nilpoint[0] = (nilpoint[0] + 1.0f) * 0.5f * vpsize[0]; nilpoint[1] = (nilpoint[1] + 1.0f) * 0.5f * vpsize[1]; #if 1 // Unfortunately, the size of the label is stored in the pimpl class of // SoText2 which cannot be accessed directly. However, there is a trick // to get the required information: set model, viewing and projection // matrix to the identity matrix and also view volume to some default // values. SoText2::computeBBox() then calls SoText2P::getQuad which // returns the sizes in form of the bounding box. These values can be // reverse-engineered to get width and height. state->push(); SoModelMatrixElement::set(state,this,SbMatrix::identity()); SoViewingMatrixElement::set(state,this,SbMatrix::identity()); SoProjectionMatrixElement::set(state,this,SbMatrix::identity()); SbViewVolume vv; vv.ortho(-1,1,-1,1,-1,1); SoViewVolumeElement::set(state,this,vv); SbBox3f box; SbVec3f center; this->computeBBox(action, box, center); state->pop(); float xmin,ymin,zmin,xmax,ymax,zmax; box.getBounds(xmin,ymin,zmin,xmax,ymax,zmax); SbVec3f v0(xmin,ymax,zmax); SbVec3f v1(xmax,ymax,zmax); SbVec3f v2(xmax,ymin,zmax); SbVec3f v3(xmin,ymin,zmax); vv.projectToScreen(v0,v0); vv.projectToScreen(v1,v1); vv.projectToScreen(v2,v2); vv.projectToScreen(v3,v3); float width,height; width = (v1[0]-v0[0])*vpsize[0]; height = (v1[1]-v3[1])*vpsize[1]; switch (this->justification.getValue()) { case SoText2::RIGHT: nilpoint[0] -= width; break; case SoText2::CENTER: nilpoint[0] -= 0.5f*width; break; default: break; } if (lines > 1) { nilpoint[1] -= (float(lines-1)/(float)lines*height); } #else // Unfortunately, the required size (in pixels) is stored in a non-accessible way // in the subclass SoText2. Thus, we try to get a satisfactory solution with Qt // methods. // The font name is of the form "family:style". If 'style' is given it can be // 'Bold', 'Italic' or 'Bold Italic'. QFont font; QString fn = QString::fromAscii(fontname.getString()); int pos = fn.indexOf(QLatin1Char(':')); if (pos > -1) { if (fn.indexOf(QLatin1String("Bold"),pos,Qt::CaseInsensitive) > pos) font.setBold(true); if (fn.indexOf(QLatin1String("Italic"),pos,Qt::CaseInsensitive) > pos) font.setItalic(true); fn = fn.left(pos); } font.setFamily(fn); font.setPixelSize((int)fontsize); QFontMetrics fm(font); float width = 0.0f; float height = 0.75f*fontsize*lines + (lines-1)*space;//fm.height(); float hh=0; for (int i = 0; i < lines; i++) { SbString str = this->string[i]; float w = fm.width(QLatin1String(this->string[i].getString())); width = std::max<float>(width, w); hh = fm.height(); } if (lines > 1) { nilpoint[1] -= ((lines-1)*fontsize*0.75f+space); } #endif SbVec3f toppoint = nilpoint; toppoint[0] += width; toppoint[1] += height; // Set new state. glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, vpsize[0], 0, vpsize[1], -1.0f, 1.0f); glPixelStorei(GL_UNPACK_ALIGNMENT,1); state->push(); // disable textures for all units SoGLTextureEnabledElement::set(state, this, FALSE); SoGLTexture3EnabledElement::set(state, this, FALSE); glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT); glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); // color and frame size SbColor color = this->backgroundColor.getValue(); float fs = this->frameSize.getValue(); // draw background glColor3f(color[0], color[1], color[2]); glBegin(GL_QUADS); glVertex3f(nilpoint[0]-fs,nilpoint[1]-fs,0.0f); glVertex3f(toppoint[0]+fs,nilpoint[1]-fs,0.0f); glVertex3f(toppoint[0]+fs,toppoint[1]+fs,0.0f); glVertex3f(nilpoint[0]-fs,toppoint[1]+fs,0.0f); glEnd(); // pop old state glPopClientAttrib(); glPopAttrib(); state->pop(); glPixelStorei(GL_UNPACK_ALIGNMENT,4); // Pop old GL matrix state. glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } state->pop(); inherited::GLRender(action); }