void SoBrepPointSet::renderHighlight(SoGLRenderAction *action) { SoState * state = action->getState(); state->push(); float ps = SoPointSizeElement::get(state); if (ps < 4.0f) SoPointSizeElement::set(state, this, 4.0f); SoLazyElement::setEmissive(state, &this->highlightColor); SoOverrideElement::setEmissiveColorOverride(state, this, true); SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker); SoOverrideElement::setDiffuseColorOverride(state, this, true); const SoCoordinateElement * coords; const SbVec3f * normals; this->getVertexData(state, coords, normals, false); SoMaterialBundle mb(action); mb.sendFirst(); // make sure we have the correct material int32_t id = this->highlightIndex.getValue(); if (id < this->startIndex.getValue() || id >= coords->getNum()) { SoDebugError::postWarning("SoBrepPointSet::renderHighlight", "highlightIndex out of range"); } else { renderShape(static_cast<const SoGLCoordinateElement*>(coords), &id, 1); } state->pop(); }
// doc from parent void SoFCSelection::GLRenderInPath(SoGLRenderAction * action) { #ifdef NO_FRONTBUFFER // check if preselection is active HighlightModes mymode = (HighlightModes) this->highlightMode.getValue(); bool preselected = highlighted && mymode == AUTO; SoState * state = action->getState(); state->push(); if (preselected || this->highlightMode.getValue() == ON || this->selected.getValue() == SELECTED) { this->setOverride(action); } inherited::GLRenderInPath(action); state->pop(); #else // Set up state for locate highlighting (if necessary) GLint oldDepthFunc; SbBool drawHighlighted = preRender(action, oldDepthFunc); // now invoke the parent method inherited::GLRenderInPath(action); // Restore old depth buffer model if needed if (drawHighlighted || highlighted) glDepthFunc((GLenum)oldDepthFunc); // Clean up state if needed if (drawHighlighted) action->getState()->pop(); #endif }
void SoBrepPointSet::renderSelection(SoGLRenderAction *action) { SoState * state = action->getState(); state->push(); float ps = SoPointSizeElement::get(state); if (ps < 4.0f) SoPointSizeElement::set(state, this, 4.0f); SoLazyElement::setEmissive(state, &this->selectionColor); SoOverrideElement::setEmissiveColorOverride(state, this, true); SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker); SoOverrideElement::setDiffuseColorOverride(state, this, true); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numcindices; this->getVertexData(state, coords, normals, false); SoMaterialBundle mb(action); mb.sendFirst(); // make sure we have the correct material cindices = this->selectionIndex.getValues(0); numcindices = this->selectionIndex.getNum(); if (!validIndexes(coords, this->startIndex.getValue(), cindices, numcindices)) { SoDebugError::postWarning("SoBrepPointSet::renderSelection", "selectionIndex out of range"); } else { renderShape(static_cast<const SoGLCoordinateElement*>(coords), cindices, numcindices); } state->pop(); }
void SoBrepEdgeSet::renderHighlight(SoGLRenderAction *action) { SoState * state = action->getState(); state->push(); //SoLineWidthElement::set(state, this, 4.0f); SoLazyElement::setEmissive(state, &this->highlightColor); SoOverrideElement::setEmissiveColorOverride(state, this, TRUE); SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker1); SoOverrideElement::setDiffuseColorOverride(state, this, TRUE); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numcindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; SbBool normalCacheUsed; this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numcindices, FALSE, normalCacheUsed); SoMaterialBundle mb(action); mb.sendFirst(); // make sure we have the correct material int num = (int)this->hl.size(); if (num > 0) { const int32_t* id = &(this->hl[0]); renderShape(static_cast<const SoGLCoordinateElement*>(coords), id, num); } state->pop(); }
void SoBrepPointSet::renderHighlight(SoGLRenderAction *action) { SoState * state = action->getState(); state->push(); float ps = SoPointSizeElement::get(state); if (ps < 4.0f) SoPointSizeElement::set(state, this, 4.0f); SoLazyElement::setEmissive(state, &this->highlightColor); SoOverrideElement::setEmissiveColorOverride(state, this, TRUE); SoLazyElement::setDiffuse(state, this,1, &this->highlightColor,&this->colorpacker); SoOverrideElement::setDiffuseColorOverride(state, this, TRUE); const SoCoordinateElement * coords; const SbVec3f * normals; this->getVertexData(state, coords, normals, FALSE); SoMaterialBundle mb(action); mb.sendFirst(); // make sure we have the correct material int32_t id = this->highlightIndex.getValue(); renderShape(static_cast<const SoGLCoordinateElement*>(coords), &id, 1); state->pop(); }
/** * Renders the probe with text label and a bullet at the base point. */ void SoRegPoint::GLRender(SoGLRenderAction *action) { if (shouldGLRender(action)) { SoState* state = action->getState(); state->push(); SoMaterialBundle mb(action); SoTextureCoordinateBundle tb(action, true, false); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); mb.sendFirst(); // make sure we have the correct material SbVec3f p1 = base.getValue(); SbVec3f p2 = p1 + normal.getValue() * length.getValue(); glLineWidth(1.0f); glColor3fv(color.getValue().getValue()); glBegin(GL_LINE_STRIP); glVertex3d(p1[0], p1[1], p1[2]); glVertex3d(p2[0], p2[1], p2[2]); glEnd(); glPointSize(5.0f); glBegin(GL_POINTS); glVertex3fv(p1.getValue()); glEnd(); glPointSize(2.0f); glBegin(GL_POINTS); glVertex3fv(p2.getValue()); glEnd(); root->GLRender(action); state->pop(); } }
// Doc in parent void SoVRMLGroup::getPrimitiveCount(SoGetPrimitiveCountAction * action) { SoState * state = action->getState(); state->push(); inherited::getPrimitiveCount(action); state->pop(); }
// Doc in parent void SoVRMLGroup::doAction(SoAction * action) { SoState * state = action->getState(); state->push(); inherited::doAction(action); state->pop(); }
// Doc from superclass. void SoGeoSeparator::GLRenderInPath(SoGLRenderAction * action) { SoState * state = action->getState(); state->push(); this->applyTransformation((SoAction*) action); SoSeparator::GLRenderInPath(action); state->pop(); }
void SoVRMLShape::GLRender(SoGLRenderAction * action) { SoState * state = action->getState(); state->push(); if ((this->appearance.getValue() == NULL) || (((SoVRMLAppearance*)this->appearance.getValue())->material.getValue() == NULL)) { SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); } int numindices; const int * indices; SoAction::PathCode pathcode = action->getPathCode(numindices, indices); SoNode ** childarray = (SoNode**) this->getChildren()->getArrayPtr(); if (pathcode == SoAction::IN_PATH) { int lastchild = indices[numindices - 1]; for (int i = 0; i <= lastchild && !action->hasTerminated(); i++) { SoNode * child = childarray[i]; action->pushCurPath(i, child); if (action->getCurPathCode() != SoAction::OFF_PATH || child->affectsState()) { if (!action->abortNow()) { SoNodeProfiling profiling; profiling.preTraversal(action); child->GLRender(action); profiling.postTraversal(action); } else { SoCacheElement::invalidate(state); } } action->popCurPath(pathcode); } } else { action->pushCurPath(); int n = this->getChildren()->getLength(); for (int i = 0; i < n && !action->hasTerminated(); i++) { action->popPushCurPath(i, childarray[i]); if (action->abortNow()) { // only cache if we do a full traversal SoCacheElement::invalidate(state); break; } SoNodeProfiling profiling; profiling.preTraversal(action); childarray[i]->GLRender(action); profiling.postTraversal(action); } action->popCurPath(); } state->pop(); }
// Doc in parent void SoVRMLGroup::callback(SoCallbackAction * action) { SoState * state = action->getState(); state->push(); // culling planes should normally not be set, but can be set // manually by the application programmer to optimize callback // action traversal. if (!this->cullTest(state)) { inherited::callback(action); } state->pop(); }
// Doc from superclass. void SoGeoSeparator::getPrimitiveCount(SoGetPrimitiveCountAction * action) { SoState * state = action->getState(); state->push(); this->applyTransformation((SoAction *)action); SoSeparator::getPrimitiveCount(action); state->pop(); }
// Doc from superclass. void SoGeoSeparator::rayPick(SoRayPickAction * action) { SoState * state = action->getState(); state->push(); this->applyTransformation((SoAction *)action); SoSeparator::rayPick(action); state->pop(); }
// Doc in parent void SoVRMLGroup::GLRenderInPath(SoGLRenderAction * action) { int numindices; const int * indices; SoAction::PathCode pathcode = action->getPathCode(numindices, indices); if (pathcode == SoAction::IN_PATH) { SoState * state = action->getState(); SoNode ** childarray = (SoNode**) this->getChildren()->getArrayPtr(); state->push(); int childidx = 0; for (int i = 0; i < numindices; i++) { for (; childidx < indices[i] && !action->hasTerminated(); childidx++) { SoNode * offpath = childarray[childidx]; if (offpath->affectsState()) { action->pushCurPath(childidx, offpath); if (!action->abortNow()) { SoNodeProfiling profiling; profiling.preTraversal(action); offpath->GLRenderOffPath(action); profiling.postTraversal(action); } else { SoCacheElement::invalidate(state); } action->popCurPath(pathcode); } } SoNode * inpath = childarray[childidx]; action->pushCurPath(childidx, inpath); if (!action->abortNow()) { SoNodeProfiling profiling; profiling.preTraversal(action); inpath->GLRenderInPath(action); profiling.postTraversal(action); } else { SoCacheElement::invalidate(state); } action->popCurPath(pathcode); childidx++; } state->pop(); } else { // we got to the end of the path assert(action->getCurPathCode() == SoAction::BELOW_PATH); this->GLRenderBelowPath(action); } }
void SoBoxHighlightRenderAction::drawBoxes(SoPath * pathtothis, const SoPathList * pathlist) { int i; int thispos = reclassify_cast<SoFullPath *>(pathtothis)->getLength()-1; assert(thispos >= 0); PRIVATE(this)->postprocpath->setHead(pathtothis->getHead()); // reset for (i = 1; i < thispos; i++) { PRIVATE(this)->postprocpath->append(pathtothis->getIndex(i)); } // we need to disable accumulation buffer antialiasing while // rendering selected objects int oldnumpasses = this->getNumPasses(); this->setNumPasses(1); SoState * thestate = this->getState(); thestate->push(); for (i = 0; i < pathlist->getLength(); i++) { SoFullPath * path = reclassify_cast<SoFullPath *>((*pathlist)[i]); PRIVATE(this)->postprocpath->append(path->getHead()); for (int j = 1; j < path->getLength(); j++) { PRIVATE(this)->postprocpath->append(path->getIndex(j)); } // Previously SoGLRenderAction was used to draw the bounding boxes // of shapes in selection paths, by overriding renderstyle state // elements to lines drawstyle and simply doing: // // SoGLRenderAction::apply(PRIVATE(this)->postprocpath); // Bug // // This could have the unwanted side effect of rendering // non-selected shapes, as they could be part of the path (due to // being placed below SoGroup nodes (instead of SoSeparator // nodes)) up to the selected shape. // // // A better approach turned out to be to soup up and draw only the // bounding boxes of the selected shapes: PRIVATE(this)->drawHighlightBox(PRIVATE(this)->postprocpath); // Remove temporary path from path buffer PRIVATE(this)->postprocpath->truncate(thispos); } this->setNumPasses(oldnumpasses); thestate->pop(); }
void SoVRMLShape::getBoundingBox(SoGetBoundingBoxAction * action) { SoState * state = action->getState(); state->push(); int numindices; const int * indices; if (action->getPathCode(numindices, indices) == SoAction::IN_PATH) { this->getChildren()->traverseInPath(action, numindices, indices); } else { this->getChildren()->traverse(action); // traverse all children } state->pop(); }
// Doc from superclass. void SoGeoSeparator::getBoundingBox(SoGetBoundingBoxAction * action) { SoState * state = action->getState(); state->push(); SbMatrix m = this->getTransform(state); SoModelMatrixElement::mult(state, this, SoModelMatrixElement::get(state).inverse()); SoModelMatrixElement::mult(state, this, m); SoSeparator::getBoundingBox(action); state->pop(); }
void SoBrepEdgeSet::renderSelection(SoGLRenderAction *action) { int numSelected = this->selectionIndex.getNum(); if (numSelected == 0) return; SoState * state = action->getState(); state->push(); //SoLineWidthElement::set(state, this, 4.0f); SoLazyElement::setEmissive(state, &this->selectionColor); SoOverrideElement::setEmissiveColorOverride(state, this, true); SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker2); SoOverrideElement::setDiffuseColorOverride(state, this, true); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numcindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; SbBool normalCacheUsed; this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numcindices, false, normalCacheUsed); SoMaterialBundle mb(action); mb.sendFirst(); // make sure we have the correct material int num = (int)this->sl.size(); if (num > 0) { cindices = &(this->sl[0]); numcindices = (int)this->sl.size(); if (!validIndexes(coords, this->sl)) { SoDebugError::postWarning("SoBrepEdgeSet::renderSelection", "selectionIndex out of range"); } else { renderShape(static_cast<const SoGLCoordinateElement*>(coords), cindices, numcindices); } } state->pop(); }
void SoXipPlot2Columns::GLRender( SoGLRenderAction* action ) { SoXipPlot2Element::add( action->getState(), this, label.getValue(), borderColor.getValue(), faceColor.getValue() ); SoState* state = action->getState(); state->push(); // Make sure the DrawStyle is set to FILLED SoDrawStyleElement::set( state, SoDrawStyleElement::FILLED ); SoBaseKit::GLRender( action ); state->pop(); }
void SoXipPlot2Ruler::GLRender( SoGLRenderAction* action ) { SoState* state = action->getState(); if( !state ) return ; state->push(); mBBox = SoXipPlot2AreaElement::getBBox( state ); int numValues = value.getNum(); mCoord->point.setNum( 2 * numValues ); mLineSet->numVertices.setNum( numValues ); if( type.getValue() == HORIZONTAL ) { for( int i = 0; i < numValues; ++ i ) { mCoord->point.set1Value( 2*i, SbVec3f( mBBox.getMin()[0], value[i], 0 ) ); mCoord->point.set1Value( 1 + 2*i, SbVec3f( mBBox.getMax()[0], value[i], 0 ) ); mLineSet->numVertices.set1Value( i, 2 ); } } else { for( int i = 0; i < numValues; ++ i ) { mCoord->point.set1Value( 2*i, SbVec3f( value[i], mBBox.getMin()[1], 0 ) ); mCoord->point.set1Value( 1 + 2*i, SbVec3f( value[i], mBBox.getMax()[1], 0 ) ); mLineSet->numVertices.set1Value( i, 2 ); } } action->traverse( mCoord ); action->traverse( mLineSet ); state->pop(); }
void SoWidgetShape::generatePrimitives(SoAction *action) { if (this->image.isNull()) return; SoState *state = action->getState(); state->push(); SbVec2s size; SbVec3f v0, v1, v2, v3; this->getQuad(action->getState(), v0, v1, v2, v3); SbVec3f n = (v1-v0).cross(v2-v0); n.normalize(); this->beginShape(action, SoShape::QUADS); SoPrimitiveVertex vertex; vertex.setNormal(n); vertex.setTextureCoords(SbVec2f(0,0)); vertex.setPoint(v0); this->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(1,0)); vertex.setPoint(v1); this->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(1,1)); vertex.setPoint(v2); this->shapeVertex(&vertex); vertex.setTextureCoords(SbVec2f(0,1)); vertex.setPoint(v3); this->shapeVertex(&vertex); this->endShape(); state->pop(); }
void SoVRMLShape::doAction(SoAction * action) { SoState * state = action->getState(); if (state->isElementEnabled(SoLazyElement::getClassStackIndex())) { if ((this->appearance.getValue() == NULL) || (((SoVRMLAppearance*)this->appearance.getValue())->material.getValue() == NULL)) { SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); } } state->push(); int numindices; const int * indices; if (action->getPathCode(numindices, indices) == SoAction::IN_PATH) { this->getChildren()->traverseInPath(action, numindices, indices); } else { this->getChildren()->traverse(action); // traverse all children } state->pop(); }
// // internal method which checks if convex cache needs to be // used or (re)created. Returns TRUE if convex cache must be // used. PRIVATE(this)->convexCache is then guaranteed to be != NULL. // SbBool SoVRMLIndexedFaceSet::useConvexCache(SoAction * action, const SbVec3f * normals, const int32_t * nindices, const SbBool normalsfromcache) { SoState * state = action->getState(); if (this->convex.getValue()) return FALSE; if (PRIVATE(this)->concavestatus == STATUS_UNKNOWN) { const int32_t * ptr = this->coordIndex.getValues(0); const int32_t * endptr = ptr + this->coordIndex.getNum(); int cnt = 0; PRIVATE(this)->concavestatus = STATUS_CONVEX; while (ptr < endptr) { if (*ptr++ >= 0) cnt++; else { if (cnt > 3) { PRIVATE(this)->concavestatus = STATUS_CONCAVE; break; } cnt = 0; } } } if (PRIVATE(this)->concavestatus == STATUS_CONVEX) return FALSE; PRIVATE(this)->readLockConvexCache(); if (PRIVATE(this)->convexCache && PRIVATE(this)->convexCache->isValid(state)) { // check if convex cache has normal indices. The convex cache // might be generated without normals. if (normals == NULL || PRIVATE(this)->convexCache->getNormalIndices()) { return TRUE; } } PRIVATE(this)->readUnlockConvexCache(); PRIVATE(this)->writeLockConvexCache(); if (PRIVATE(this)->convexCache) PRIVATE(this)->convexCache->unref(); SbBool storedinvalid = SoCacheElement::setInvalid(FALSE); // need to send matrix if we have some weird transformation SbMatrix modelmatrix = SoModelMatrixElement::get(state); if (modelmatrix[3][0] == 0.0f && modelmatrix[3][1] == 0.0f && modelmatrix[3][2] == 0.0f && modelmatrix[3][3] == 1.0f) modelmatrix = SbMatrix::identity(); // push to create cache dependencies state->push(); PRIVATE(this)->convexCache = new SoConvexDataCache(state); PRIVATE(this)->convexCache->ref(); SoCacheElement::set(state, PRIVATE(this)->convexCache); SoVRMLVertexShape::doAction(action); const SoCoordinateElement * coords; const int32_t * cindices; const SbVec3f * dummynormals; int numindices; const int32_t * dummynindices; const int32_t * tindices; const int32_t * mindices; SbBool dummy; this->getVertexData(state, coords, dummynormals, cindices, dummynindices, tindices, mindices, numindices, FALSE, dummy); Binding mbind = this->findMaterialBinding(state); Binding nbind = normals ? this->findNormalBinding(state) : OVERALL; if (normalsfromcache && nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; } if (mbind == PER_VERTEX) { mbind = PER_VERTEX_INDEXED; mindices = tindices; } if (nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; nindices = cindices; } Binding tbind = PER_VERTEX_INDEXED; if (tindices == NULL) tindices = cindices; if (nbind == PER_VERTEX_INDEXED && nindices == NULL) { nindices = cindices; } if (mbind == PER_VERTEX_INDEXED && mindices == NULL) { mindices = cindices; } PRIVATE(this)->convexCache->generate(coords, modelmatrix, cindices, numindices, mindices, nindices, tindices, (SoConvexDataCache::Binding)mbind, (SoConvexDataCache::Binding)nbind, (SoConvexDataCache::Binding)tbind); PRIVATE(this)->writeUnlockConvexCache(); state->pop(); SoCacheElement::setInvalid(storedinvalid); PRIVATE(this)->readLockConvexCache(); return TRUE; }
// Doc in parent void SoVRMLIndexedFaceSet::generatePrimitives(SoAction * action) { if (this->coordIndex.getNum() < 3) return; SoState * state = action->getState(); state->push(); SoVRMLVertexShape::doAction(action); Binding mbind = this->findMaterialBinding(state); Binding nbind = this->findNormalBinding(state); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; SbBool doTextures; SbBool sendNormals; SbBool normalCacheUsed; sendNormals = TRUE; // always generate normals this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numindices, sendNormals, normalCacheUsed); if (!sendNormals) { nbind = OVERALL; normals = NULL; nindices = NULL; } else if (normalCacheUsed && nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; } else if (normalCacheUsed && nbind == PER_FACE_INDEXED) { nbind = PER_FACE; } if (mbind == PER_VERTEX) { mbind = PER_VERTEX_INDEXED; mindices = cindices; } if (nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; nindices = cindices; } SoTextureCoordinateBundle tb(action, FALSE, FALSE); doTextures = tb.needCoordinates(); Binding tbind = NONE; if (doTextures) { if (tb.isFunction() && !tb.needIndices()) { tbind = NONE; tindices = NULL; } else { tbind = PER_VERTEX_INDEXED; if (tindices == NULL) tindices = cindices; } } SbBool convexcacheused = FALSE; if (this->useConvexCache(action, normals, nindices, normalCacheUsed)) { cindices = PRIVATE(this)->convexCache->getCoordIndices(); numindices = PRIVATE(this)->convexCache->getNumCoordIndices(); mindices = PRIVATE(this)->convexCache->getMaterialIndices(); nindices = PRIVATE(this)->convexCache->getNormalIndices(); tindices = PRIVATE(this)->convexCache->getTexIndices(); if (mbind == PER_VERTEX) mbind = PER_VERTEX_INDEXED; else if (mbind == PER_FACE) mbind = PER_FACE_INDEXED; if (nbind == PER_VERTEX) nbind = PER_VERTEX_INDEXED; else if (nbind == PER_FACE) nbind = PER_FACE_INDEXED; if (tbind != NONE) tbind = PER_VERTEX_INDEXED; convexcacheused = TRUE; } int texidx = 0; TriangleShape mode = POLYGON; TriangleShape newmode; const int32_t *viptr = cindices; const int32_t *viendptr = viptr + numindices; int32_t v1, v2, v3, v4, v5 = 0; // v5 init unnecessary, but kills a compiler warning. SoPrimitiveVertex vertex; SoPointDetail pointDetail; SoFaceDetail faceDetail; vertex.setDetail(&pointDetail); SbVec3f dummynormal(0,0,1); const SbVec3f *currnormal = &dummynormal; if (normals) currnormal = normals; vertex.setNormal(*currnormal); int matnr = 0; int normnr = 0; while (viptr + 2 < viendptr) { v1 = *viptr++; v2 = *viptr++; v3 = *viptr++; assert(v1 >= 0 && v2 >= 0 && v3 >= 0); v4 = viptr < viendptr ? *viptr++ : -1; if (v4 < 0) newmode = TRIANGLES; else { v5 = viptr < viendptr ? *viptr++ : -1; if (v5 < 0) newmode = QUADS; else newmode = POLYGON; } if (newmode != mode) { if (mode != POLYGON) this->endShape(); mode = newmode; this->beginShape(action, mode, &faceDetail); } else if (mode == POLYGON) this->beginShape(action, POLYGON, &faceDetail); // vertex 1 can't use DO_VERTEX if (mbind == PER_VERTEX || mbind == PER_FACE) { pointDetail.setMaterialIndex(matnr); vertex.setMaterialIndex(matnr++); } else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { pointDetail.setMaterialIndex(*mindices); vertex.setMaterialIndex(*mindices++); } if (nbind == PER_VERTEX || nbind == PER_FACE) { pointDetail.setNormalIndex(normnr); currnormal = &normals[normnr++]; vertex.setNormal(*currnormal); } else if (nbind == PER_FACE_INDEXED || nbind == PER_VERTEX_INDEXED) { pointDetail.setNormalIndex(*nindices); currnormal = &normals[*nindices++]; vertex.setNormal(*currnormal); } if (tb.isFunction()) { vertex.setTextureCoords(tb.get(coords->get3(v1), *currnormal)); if (tb.needIndices()) pointDetail.setTextureCoordIndex(tindices ? *tindices++ : texidx++); } else if (tbind != NONE) { pointDetail.setTextureCoordIndex(tindices ? *tindices : texidx); vertex.setTextureCoords(tb.get(tindices ? *tindices++ : texidx++)); } pointDetail.setCoordinateIndex(v1); vertex.setPoint(coords->get3(v1)); this->shapeVertex(&vertex); DO_VERTEX(v2); DO_VERTEX(v3); if (mode != TRIANGLES) { DO_VERTEX(v4); if (mode == POLYGON) { DO_VERTEX(v5); v1 = viptr < viendptr ? *viptr++ : -1; while (v1 >= 0) { DO_VERTEX(v1); v1 = viptr < viendptr ? *viptr++ : -1; } this->endShape(); } } faceDetail.incFaceIndex(); if (mbind == PER_VERTEX_INDEXED) { mindices++; } if (nbind == PER_VERTEX_INDEXED) { nindices++; } if (tindices) tindices++; } if (mode != POLYGON) this->endShape(); if (normalCacheUsed) { this->readUnlockNormalCache(); } if (convexcacheused) { PRIVATE(this)->readUnlockConvexCache(); } state->pop(); }
// Doc in parent void SoVRMLIndexedFaceSet::GLRender(SoGLRenderAction * action) { if (this->coordIndex.getNum() < 3 || this->coord.getValue() == NULL) return; SoState * state = action->getState(); state->push(); // update state with coordinates, normals and texture information SoVRMLVertexShape::GLRender(action); if (!this->shouldGLRender(action)) { state->pop(); return; } this->setupShapeHints(state, this->ccw.getValue(), this->solid.getValue()); Binding mbind = this->findMaterialBinding(state); Binding nbind = this->findNormalBinding(state); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; SbBool doTextures; SbBool normalCacheUsed; SoMaterialBundle mb(action); SoTextureCoordinateBundle tb(action, TRUE, FALSE); doTextures = tb.needCoordinates(); SbBool sendNormals = !mb.isColorOnly() || tb.isFunction(); this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numindices, sendNormals, normalCacheUsed); if (!sendNormals) { nbind = OVERALL; normals = NULL; nindices = NULL; } else if (nbind == OVERALL) { if (normals) glNormal3fv(normals[0].getValue()); else glNormal3f(0.0f, 0.0f, 1.0f); } else if (normalCacheUsed && nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; } else if (normalCacheUsed && nbind == PER_FACE_INDEXED) { nbind = PER_FACE; } if (mbind == PER_VERTEX) { mbind = PER_VERTEX_INDEXED; mindices = cindices; } if (nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; nindices = cindices; } Binding tbind = NONE; if (doTextures) { if (tb.isFunction() && !tb.needIndices()) { tbind = NONE; tindices = NULL; } else { tbind = PER_VERTEX_INDEXED; if (tindices == NULL) tindices = cindices; } } SbBool convexcacheused = FALSE; if (this->useConvexCache(action, normals, nindices, normalCacheUsed)) { cindices = PRIVATE(this)->convexCache->getCoordIndices(); numindices = PRIVATE(this)->convexCache->getNumCoordIndices(); mindices = PRIVATE(this)->convexCache->getMaterialIndices(); nindices = PRIVATE(this)->convexCache->getNormalIndices(); tindices = PRIVATE(this)->convexCache->getTexIndices(); if (mbind == PER_VERTEX) mbind = PER_VERTEX_INDEXED; else if (mbind == PER_FACE) mbind = PER_FACE_INDEXED; if (nbind == PER_VERTEX) nbind = PER_VERTEX_INDEXED; else if (nbind == PER_FACE) nbind = PER_FACE_INDEXED; if (tbind != NONE) tbind = PER_VERTEX_INDEXED; convexcacheused = TRUE; } mb.sendFirst(); // make sure we have the correct material SoGLLazyElement * lelem = NULL; const uint32_t contextid = action->getCacheContext(); SbBool dova = SoVBO::shouldRenderAsVertexArrays(state, contextid, numindices) && !convexcacheused && !normalCacheUsed && ((nbind == OVERALL) || ((nbind == PER_VERTEX_INDEXED) && ((nindices == cindices) || (nindices == NULL)))) && ((tbind == NONE && !tb.needCoordinates()) || ((tbind == PER_VERTEX_INDEXED) && ((tindices == cindices) || (tindices == NULL)))) && ((mbind == NONE) || ((mbind == PER_VERTEX_INDEXED) && ((mindices == cindices) || (mindices == NULL)))) && SoGLDriverDatabase::isSupported(sogl_glue_instance(state), SO_GL_VERTEX_ARRAY); const SoGLVBOElement * vboelem = SoGLVBOElement::getInstance(state); SoVBO * colorvbo = NULL; if (dova && (mbind != OVERALL)) { dova = FALSE; if ((mbind == PER_VERTEX_INDEXED) && ((mindices == cindices) || (mindices == NULL))) { lelem = (SoGLLazyElement*) SoLazyElement::getInstance(state); colorvbo = vboelem->getColorVBO(); if (colorvbo) dova = TRUE; else { // we might be able to do VA-rendering, but need to check the // diffuse color type first. if (!lelem->isPacked() && lelem->getNumTransparencies() <= 1) { dova = TRUE; } } } } SbBool didrenderasvbo = FALSE; if (dova) { SbBool dovbo = this->startVertexArray(action, coords, (nbind != OVERALL) ? normals : NULL, doTextures, mbind != OVERALL); didrenderasvbo = dovbo; LOCK_VAINDEXER(this); if (PRIVATE(this)->vaindexer == NULL) { SoVertexArrayIndexer * indexer = new SoVertexArrayIndexer; int i = 0; while (i < numindices) { int cnt = 0; while (i + cnt < numindices && cindices[i+cnt] >= 0) cnt++; switch (cnt) { case 3: indexer->addTriangle(cindices[i],cindices[i+1], cindices[i+2]); break; case 4: indexer->addQuad(cindices[i],cindices[i+1],cindices[i+2],cindices[i+3]); break; default: if (cnt > 4) { indexer->beginTarget(GL_POLYGON); for (int j = 0; j < cnt; j++) { indexer->targetVertex(GL_POLYGON, cindices[i+j]); } indexer->endTarget(GL_POLYGON); } } i += cnt + 1; } indexer->close(); if (indexer->getNumVertices()) { PRIVATE(this)->vaindexer = indexer; } else { delete indexer; } #if 0 fprintf(stderr,"XXX: create VRML VertexArrayIndexer: %d\n", indexer->getNumVertices()); #endif } if (PRIVATE(this)->vaindexer) { PRIVATE(this)->vaindexer->render(sogl_glue_instance(state), dovbo, contextid); } UNLOCK_VAINDEXER(this); this->finishVertexArray(action, dovbo, (nbind != OVERALL), doTextures, mbind != OVERALL); } else { SoVertexAttributeBundle vab(action, TRUE); SbBool doattribs = vab.doAttributes(); SoVertexAttributeBindingElement::Binding attribbind = SoVertexAttributeBindingElement::get(state); if (!doattribs) { // for overall attribute binding we check for doattribs before // sending anything in SoGL::FaceSet::GLRender attribbind = SoVertexAttributeBindingElement::OVERALL; } sogl_render_faceset((SoGLCoordinateElement *)coords, cindices, numindices, normals, nindices, &mb, mindices, &tb, tindices, &vab, (int)nbind, (int)mbind, (int)attribbind, doTextures ? 1 : 0, doattribs ? 1 : 0); } if (normalCacheUsed) { this->readUnlockNormalCache(); } if (convexcacheused) { PRIVATE(this)->readUnlockConvexCache(); } // send approx number of triangles for autocache handling sogl_autocache_update(state, this->coordIndex.getNum() / 4, didrenderasvbo); state->pop(); }
void SoLineHighlightRenderActionP::drawBoxes(SoPath * pathtothis, const SoPathList * pathlist) { int i; int thispos = reclassify_cast<SoFullPath *>(pathtothis)->getLength()-1; assert(thispos >= 0); this->postprocpath->setHead(pathtothis->getHead()); // reset for (i = 1; i < thispos; i++) { this->postprocpath->append(pathtothis->getIndex(i)); } SoState * state = PUBLIC(this)->getState(); state->push(); // we need to disable accumulation buffer antialiasing while // rendering selected objects int oldnumpasses = PUBLIC(this)->getNumPasses(); PUBLIC(this)->setNumPasses(1); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); SoColorPacker ** cptr = static_cast<SoColorPacker **>(this->colorpacker_storage.get()); SoLazyElement::setDiffuse(state, pathtothis->getHead(), 1, &this->color, *cptr); // FIXME: we should check this versus the actual max line width // supported by the underlying OpenGL context. 20050610 mortene. SoLineWidthElement::set(state, this->linewidth); SoLinePatternElement::set(state, this->linepattern); SoTextureQualityElement::set(state, 0.0f); SoDrawStyleElement::set(state, SoDrawStyleElement::LINES); SoPolygonOffsetElement::set(state, NULL, -1.0f, -1.0f, SoPolygonOffsetElement::LINES, TRUE); SoMaterialBindingElement::set(state, NULL, SoMaterialBindingElement::OVERALL); SoNormalElement::set(state, NULL, 0, NULL, FALSE); SoOverrideElement::setNormalVectorOverride(state, NULL, TRUE); SoOverrideElement::setMaterialBindingOverride(state, NULL, TRUE); SoOverrideElement::setLightModelOverride(state, NULL, TRUE); SoOverrideElement::setDiffuseColorOverride(state, NULL, TRUE); SoOverrideElement::setLineWidthOverride(state, NULL, TRUE); SoOverrideElement::setLinePatternOverride(state, NULL, TRUE); SoOverrideElement::setDrawStyleOverride(state, NULL, TRUE); SoOverrideElement::setPolygonOffsetOverride(state, NULL, TRUE); SoTextureOverrideElement::setQualityOverride(state, TRUE); for (i = 0; i < pathlist->getLength(); i++) { SoFullPath * path = reclassify_cast<SoFullPath *>((*pathlist)[i]); this->postprocpath->append(path->getHead()); for (int j = 1; j < path->getLength(); j++) { this->postprocpath->append(path->getIndex(j)); } PUBLIC(this)->SoGLRenderAction::apply(this->postprocpath); this->postprocpath->truncate(thispos); } PUBLIC(this)->setNumPasses(oldnumpasses); state->pop(); }
void CvrIndexedSetRenderBaseP::GLRender(SoGLRenderAction * action, const float offset, const SbBool clipGeometry) { // FIXME: Support for 'offset' must be implemented. (20040628 // handegar) if (offset != 0) { static SbBool flag = FALSE; if (!flag) { SoDebugError::postWarning("CvrIndexedSetRenderBaseP::GLRender", "Support for offset > 0 not implemented yet."); flag = TRUE; } } const cc_glglue * glue = cc_glglue_instance(action->getCacheContext()); if (!cc_glglue_has_3d_textures(glue)) { static SbBool flag = FALSE; if (!flag) { SoDebugError::postWarning("CvrIndexedSetRenderBaseP::GLRender", "Your OpenGL driver does not support 3D " "textures, which is needed for rendering " "SoVolumeIndexedFaceSet and " "SoVolumeIndexedTriangleStripSet " "nodes"); flag = TRUE; } return; } SoState * state = action->getState(); const CvrVoxelBlockElement * vbelem = CvrVoxelBlockElement::getInstance(state); if (vbelem == NULL) { return; } // This must be done, as we want to control stuff in the GL state // machine. Without it, state changes could trigger outside our // control. state->push(); SbMatrix volumetransform; CvrUtil::getTransformFromVolumeBoxDimensions(vbelem, volumetransform); SoModelMatrixElement::mult(state, this->master, volumetransform); const SbVec3s & dims = vbelem->getVoxelCubeDimensions(); SbVec3f origo(-((float) dims[0]) / 2.0f, -((float) dims[1]) / 2.0f, -((float) dims[2]) / 2.0f); // This must be done, as we want to control stuff in the GL state // machine. Without it, state changes could trigger outside our // control. SoGLLazyElement::getInstance(state)->send(state, SoLazyElement::ALL_MASK); glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_TEXTURE_3D); glEnable(GL_DEPTH_TEST); // FIXME: Should there be support for other blending methods aswell? (20040630 handegar) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (!this->cube) { this->cube = new Cvr3DTexCube(action); } const SoTransferFunctionElement * tfelement = SoTransferFunctionElement::getInstance(state); const CvrCLUT * c = CvrVoxelChunk::getCLUT(tfelement, CvrCLUT::ALPHA_AS_IS); if (this->clut != c) { this->cube->setPalette(c); this->clut = c; } // Fetch texture quality float texturequality = SoTextureQualityElement::get(state); GLenum interp; if (texturequality >= 0.1f) { interp = GL_LINEAR; } else { interp = GL_NEAREST; } CvrGLInterpolationElement::set(state, interp); // Fetch vertices and normals from the stack const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; SbBool doTextures; SbBool normalCacheUsed; doTextures = FALSE; // No need for texture coordinates SbBool sendNormals = FALSE; // No need for normals this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numindices, sendNormals, normalCacheUsed); const SbVec3f * vertexarray; SoVertexProperty * vertprop = (SoVertexProperty *) this->master->vertexProperty.getValue(); if (vertprop != NULL) { vertexarray = vertprop->vertex.getValues(0); } else vertexarray = coords->getArrayPtr3(); if (normals == NULL) glDisable(GL_LIGHTING); const Cvr3DTexCube::IndexedSetType type = ((this->type == FACESET) ? Cvr3DTexCube::INDEXEDFACE_SET : Cvr3DTexCube::INDEXEDTRIANGLESTRIP_SET); this->cube->renderIndexedSet(action, vertexarray, cindices, numindices, type); glPopAttrib(); // 'un-Transform' model matrix before rendering clip geometry. state->pop(); // Render the geometry which are outside the volume cube as polygons. if (clipGeometry) { // Is there a clipplane left for us to use? GLint maxclipplanes = 0; glGetIntegerv(GL_MAX_CLIP_PLANES, &maxclipplanes); const SoClipPlaneElement * elem = SoClipPlaneElement::getInstance(state); if (elem->getNum() > (maxclipplanes-1)) { static SbBool flag = FALSE; if (!flag) { flag = TRUE; SoDebugError::postWarning("CvrIndexedSetRenderBaseP::GLRender", "\"clipGeometry TRUE\": Not enough clip planes available. (max=%d)", maxclipplanes); } return; } if (this->parentnodeid != this->master->getNodeId()) { // Changed recently? SoVertexProperty * vertprop = (SoVertexProperty *) this->master->vertexProperty.getValue(); if (vertprop != NULL) this->clipgeometryshape->vertexProperty.setValue(vertprop); this->clipgeometryshape->coordIndex.setNum(this->master->coordIndex.getNum()); this->clipgeometryshape->materialIndex.setNum(this->master->materialIndex.getNum()); int32_t * idst = this->clipgeometryshape->coordIndex.startEditing(); int32_t * mdst = this->clipgeometryshape->materialIndex.startEditing(); int i=0; for (i=0;i<this->master->coordIndex.getNum();++i) *idst++ = this->master->coordIndex[i]; for (i=0;i<this->master->materialIndex.getNum();++i) *mdst++ = this->master->materialIndex[i]; // No need to copy texture coords as the face set shall always be untextured. this->parentnodeid = this->master->getNodeId(); this->clipgeometryshape->coordIndex.finishEditing(); this->clipgeometryshape->materialIndex.finishEditing(); } SbPlane cubeplanes[6]; SbVec3f a, b, c; // FIXME: Its really not necessary to calculate the clip planes // for each frame unless the volume has changed. This should be // optimized somehow.(20040629 handegar) volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, dims[1], 0.0f)), a); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, dims[1], dims[2])), b); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], dims[1], 0.0f)), c); cubeplanes[0] = SbPlane(a, b, c); // Top volumetransform.multVecMatrix(SbVec3f(origo), a); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], 0.0f, 0.0f)), b); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, 0.0f, dims[2])), c); cubeplanes[1] = SbPlane(a, b, c); // Bottom volumetransform.multVecMatrix(SbVec3f(origo), a); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, dims[1], 0.0f)), b); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], 0.0f, 0.0f)), c); cubeplanes[2] = SbPlane(a, b, c); // Back volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, 0.0f, dims[2])), a); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], 0.0f, dims[2])), b); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, dims[1], dims[2])), c); cubeplanes[3] = SbPlane(a, b, c); // Front volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], 0.0f, 0.0f)), a); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], dims[1], 0.0f)), b); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(dims[0], 0.0f, dims[2])), c); cubeplanes[4] = SbPlane(a, b, c); // Right volumetransform.multVecMatrix(SbVec3f(origo), a); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, 0.0f, dims[2])), b); volumetransform.multVecMatrix(SbVec3f(origo + SbVec3f(0.0f, dims[1], 0.0f)), c); cubeplanes[5] = SbPlane(a, b, c); // Left for (int i=0;i<6;++i) { state->push(); // FIXME: It would have been nice to have a 'remove' or a 'replace' // method in the SoClipPlaneElement so that we wouldn't have to // push and pop the state. (20040630 handegar) SoClipPlaneElement::add(state, this->master, cubeplanes[i]); this->clipgeometryshape->GLRender(action); state->pop(); } } }
/** * Renders the open edges only. */ void SoFrameLabel::GLRender(SoGLRenderAction *action) { inherited::GLRender(action); #if 0 QGLWidget* window; SoState * state = action->getState(); state->push(); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); SoGLWidgetElement::get(state, window); if (!window) { state->pop(); return; } // Enter in 2D screen mode glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1,1,-1,1,-1,1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); QFont font; font.setStyleStrategy(QFont::NoAntialias); font.setFamily(QLatin1String(this->name.getValue())); font.setPixelSize(this->size.getValue()); glBlendFunc(GL_ONE,GL_SRC_ALPHA); /* Background Box */ //glColor4f(1,0.1f,0.1f,1); //int ln =4; //float ls = font.pixelSize()*1.5f; //float bh = -1 + 2.0*(ls*(ln+.25))/float(window->height()); //glBegin(GL_QUADS); //glVertex2f(-1.f,bh); glVertex2f(-1.f,-1.f); //glVertex2f( 1.f,-1.f); glVertex2f( 1.f,bh); //glEnd(); //float middleCol=window->width()*0.40; //float rightCol=window->width()*0.85; //float startPos = window->height()-(5+ls*(ln)); // text color SbColor color = this->textColor.getValue(); glColor4f(color[0], color[1], color[2],1); //window->renderText(20,20/*startPos+ 1*ls*/,QLatin1String(this->string[0].getString()),font); const SbMatrix & mat = SoModelMatrixElement::get(state); const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) * SoProjectionMatrixElement::get(state)); SbVec3f nil(0.0f, 0.0f, 0.0f); projmatrix.multVecMatrix(nil, nil); QStringList list; for (int i=0; i<this->string.getNum(); i++) list << QLatin1String(this->string[i].getString()); window->renderText(nil[0],nil[1],nil[2],list.join(QLatin1String("\n")),font); // Leave 2D screen mode glPopAttrib(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); state->pop(); #endif }
void SoBrepFaceSet::renderSelection(SoGLRenderAction *action) { int numSelected = this->selectionIndex.getNum(); const int32_t* selected = this->selectionIndex.getValues(0); if (numSelected == 0) return; SoState * state = action->getState(); state->push(); SoLazyElement::setEmissive(state, &this->selectionColor); SoOverrideElement::setEmissiveColorOverride(state, this, TRUE); #if 0 // disables shading effect SoLazyElement::setDiffuse(state, this,1, &this->selectionColor,&this->colorpacker); SoOverrideElement::setDiffuseColorOverride(state, this, TRUE); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); #endif Binding mbind = this->findMaterialBinding(state); Binding nbind = this->findNormalBinding(state); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; const int32_t * pindices; SbBool doTextures; SbBool normalCacheUsed; SoMaterialBundle mb(action); SoTextureCoordinateBundle tb(action, TRUE, FALSE); doTextures = tb.needCoordinates(); SbBool sendNormals = !mb.isColorOnly() || tb.isFunction(); this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numindices, sendNormals, normalCacheUsed); mb.sendFirst(); // make sure we have the correct material // just in case someone forgot if (!mindices) mindices = cindices; if (!nindices) nindices = cindices; pindices = this->partIndex.getValues(0); // materials mbind = OVERALL; doTextures = FALSE; for (int i=0; i<numSelected; i++) { int id = selected[i]; // coords int length = (int)pindices[id]*4; int start=0; for (int j=0; j<id; j++) start+=(int)pindices[j]; start *= 4; // normals const SbVec3f * normals_s = normals; const int32_t * nindices_s = nindices; if (nbind == PER_VERTEX_INDEXED) nindices_s = &(nindices[start]); else if (nbind == PER_VERTEX) normals_s = &(normals[start]); else nbind = OVERALL; renderShape(static_cast<const SoGLCoordinateElement*>(coords), &(cindices[start]), length, &(pindices[id]), 1, normals_s, nindices_s, &mb, mindices, &tb, tindices, nbind, mbind, doTextures?1:0); } state->pop(); }
void SoBrepFaceSet::generatePrimitives(SoAction * action) { //TODO #if 0 inherited::generatePrimitives(action); #else //This is highly experimental!!! if (this->coordIndex.getNum() < 3) return; SoState * state = action->getState(); if (this->vertexProperty.getValue()) { state->push(); this->vertexProperty.getValue()->doAction(action); } Binding mbind = this->findMaterialBinding(state); Binding nbind = this->findNormalBinding(state); const SoCoordinateElement * coords; const SbVec3f * normals; const int32_t * cindices; int numindices; const int32_t * nindices; const int32_t * tindices; const int32_t * mindices; SbBool doTextures; SbBool sendNormals; SbBool normalCacheUsed; sendNormals = TRUE; // always generate normals this->getVertexData(state, coords, normals, cindices, nindices, tindices, mindices, numindices, sendNormals, normalCacheUsed); SoTextureCoordinateBundle tb(action, FALSE, FALSE); doTextures = tb.needCoordinates(); if (!sendNormals) nbind = OVERALL; else if (normalCacheUsed && nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; } else if (normalCacheUsed && nbind == PER_FACE_INDEXED) { nbind = PER_FACE; } if (this->getNodeType() == SoNode::VRML1) { // For VRML1, PER_VERTEX means per vertex in shape, not PER_VERTEX // on the state. if (mbind == PER_VERTEX) { mbind = PER_VERTEX_INDEXED; mindices = cindices; } if (nbind == PER_VERTEX) { nbind = PER_VERTEX_INDEXED; nindices = cindices; } } Binding tbind = NONE; if (doTextures) { if (tb.isFunction() && !tb.needIndices()) { tbind = NONE; tindices = NULL; } // FIXME: just call inherited::areTexCoordsIndexed() instead of // the if-check? 20020110 mortene. else if (SoTextureCoordinateBindingElement::get(state) == SoTextureCoordinateBindingElement::PER_VERTEX) { tbind = PER_VERTEX; tindices = NULL; } else { tbind = PER_VERTEX_INDEXED; if (tindices == NULL) tindices = cindices; } } if (nbind == PER_VERTEX_INDEXED && nindices == NULL) { nindices = cindices; } if (mbind == PER_VERTEX_INDEXED && mindices == NULL) { mindices = cindices; } int texidx = 0; TriangleShape mode = POLYGON; TriangleShape newmode; const int32_t *viptr = cindices; const int32_t *viendptr = viptr + numindices; const int32_t *piptr = this->partIndex.getValues(0); int num_partindices = this->partIndex.getNum(); const int32_t *piendptr = piptr + num_partindices; int32_t v1, v2, v3, v4, v5 = 0, pi; // v5 init unnecessary, but kills a compiler warning. SoPrimitiveVertex vertex; SoPointDetail pointDetail; SoFaceDetail faceDetail; vertex.setDetail(&pointDetail); SbVec3f dummynormal(0,0,1); const SbVec3f *currnormal = &dummynormal; if (normals) currnormal = normals; vertex.setNormal(*currnormal); int matnr = 0; int normnr = 0; int trinr = 0; pi = piptr < piendptr ? *piptr++ : -1; while (pi == 0) { // It may happen that a part has no triangles pi = piptr < piendptr ? *piptr++ : -1; if (mbind == PER_PART) matnr++; else if (mbind == PER_PART_INDEXED) mindices++; } while (viptr + 2 < viendptr) { v1 = *viptr++; v2 = *viptr++; v3 = *viptr++; if (v1 < 0 || v2 < 0 || v3 < 0) { break; } v4 = viptr < viendptr ? *viptr++ : -1; if (v4 < 0) newmode = TRIANGLES; else { v5 = viptr < viendptr ? *viptr++ : -1; if (v5 < 0) newmode = QUADS; else newmode = POLYGON; } if (newmode != mode) { if (mode != POLYGON) this->endShape(); mode = newmode; this->beginShape(action, mode, &faceDetail); } else if (mode == POLYGON) this->beginShape(action, POLYGON, &faceDetail); // vertex 1 can't use DO_VERTEX if (mbind == PER_PART) { if (trinr == 0) { pointDetail.setMaterialIndex(matnr); vertex.setMaterialIndex(matnr++); } } else if (mbind == PER_PART_INDEXED) { if (trinr == 0) { pointDetail.setMaterialIndex(*mindices); vertex.setMaterialIndex(*mindices++); } } else if (mbind == PER_VERTEX || mbind == PER_FACE) { pointDetail.setMaterialIndex(matnr); vertex.setMaterialIndex(matnr++); } else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) { pointDetail.setMaterialIndex(*mindices); vertex.setMaterialIndex(*mindices++); } if (nbind == PER_VERTEX || nbind == PER_FACE) { pointDetail.setNormalIndex(normnr); currnormal = &normals[normnr++]; vertex.setNormal(*currnormal); } else if (nbind == PER_FACE_INDEXED || nbind == PER_VERTEX_INDEXED) { pointDetail.setNormalIndex(*nindices); currnormal = &normals[*nindices++]; vertex.setNormal(*currnormal); } if (tb.isFunction()) { vertex.setTextureCoords(tb.get(coords->get3(v1), *currnormal)); if (tb.needIndices()) pointDetail.setTextureCoordIndex(tindices ? *tindices++ : texidx++); } else if (tbind != NONE) { pointDetail.setTextureCoordIndex(tindices ? *tindices : texidx); vertex.setTextureCoords(tb.get(tindices ? *tindices++ : texidx++)); } pointDetail.setCoordinateIndex(v1); vertex.setPoint(coords->get3(v1)); this->shapeVertex(&vertex); DO_VERTEX(v2); DO_VERTEX(v3); if (mode != TRIANGLES) { DO_VERTEX(v4); if (mode == POLYGON) { DO_VERTEX(v5); v1 = viptr < viendptr ? *viptr++ : -1; while (v1 >= 0) { DO_VERTEX(v1); v1 = viptr < viendptr ? *viptr++ : -1; } this->endShape(); } } faceDetail.incFaceIndex(); if (mbind == PER_VERTEX_INDEXED) { mindices++; } if (nbind == PER_VERTEX_INDEXED) { nindices++; } if (tindices) tindices++; trinr++; if (pi == trinr) { pi = piptr < piendptr ? *piptr++ : -1; while (pi == 0) { // It may happen that a part has no triangles pi = piptr < piendptr ? *piptr++ : -1; if (mbind == PER_PART) matnr++; else if (mbind == PER_PART_INDEXED) mindices++; } trinr = 0; } } if (mode != POLYGON) this->endShape(); if (normalCacheUsed) { this->readUnlockNormalCache(); } if (this->vertexProperty.getValue()) { state->pop(); } #endif }