bool DVRClipper::setNumAddPerVertexAttr( DVRVolume *volume, UInt32 additionalPerVertexAttributes) { numAddPerVertexAttr = additionalPerVertexAttributes; sliceVertexData = (GLdouble*) realloc( sliceVertexData, 6 * (6 + additionalPerVertexAttributes) * sizeof(GLdouble)); if(!sliceVertexData) return false; // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); if(clipObjects == NullFC) return true; for(UInt32 i = 0; i < clipObjects->count(); i++) { DVRClipGeometryPtr clipObject = clipObjects->get(i); if(!clipObject->setNumAddPerVertexAttr(additionalPerVertexAttributes)) return false; } return true; }
void DVRVolume::initializeClipObjects( DrawActionBase *action, const Matrix &volumeToWorld) { DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(this, DVRClipObjects); if(clipObjects != NullFC && clipObjects->getClipMode() != DVRClipObjects::Off) { DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture); if(tex != NullFC) { const Vec3f &res = tex->getResolution(); const Vec3f &slice = tex->getSliceThickness(); Vec3f diag(res[0] * slice[0], res[1] * slice[1], res[2] * slice[2]); Vec3f sliceDir; if(getShader()->useMTSlabs()) { Slicer::getAASlicingDirection(action,&sliceDir); } else { switch (getTextures2D()) { case 0: // 3D textures Slicer::getSlicingDirection(action, &sliceDir); break; case 1: // 2D textures Slicer::getAASlicingDirection(action, &sliceDir); break; default: // auto Window *window = action->getWindow(); if(window->hasExtension(_extTex3D)) Slicer::getSlicingDirection(action, &sliceDir); else Slicer::getAASlicingDirection(action, &sliceDir); } } Plane clipReferencePlane(sliceDir, -0.5f * diag.length()); clipObjects->initialize(volumeToWorld, clipReferencePlane); clipper.setReferencePlane(clipReferencePlane); } } }
void DVRClipper::reset(DVRVolume *volume) { if(volume == NULL || !hasTesselatorSupport) return; // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); if(clipObjects == NullFC) return; // set tesselator properties according to clip mode if(clipObjects->getClipMode() == DVRClipObjects::Intersection) { gluTessProperty(myTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ABS_GEQ_TWO); } else { gluTessProperty(myTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); } // reset local data for(UInt32 i = 0; i < clipObjects->count(); i++) { // reset i-th clip object DVRClipGeometryPtr clipObject = clipObjects->get(i); clipObject->resetLocalData (); clipObject->computeSeedVertices(); } }
void DVRClipper::clipSlice( DVRVolume *volume, DVRSlice &unclippedSlice, const Vec3f &slicingNormal, Real32 dist2RefPlane, DVRRenderSlice &clippedSlice) { const Vec3f &texScale = unclippedSlice.getTextureScale (); const Vec3f &texTranslate = unclippedSlice.getTextureTranslate(); // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); // nothing to clip with? if(clipObjects == NullFC) { DVRRenderSlicePrimitive *newPrimitive = new DVRRenderSlicePrimitive(); newPrimitive->type = GL_TRIANGLE_FAN; for(UInt32 i = 0; i < unclippedSlice.getVertexCount(); i++) { UInt32 idx = (6+numAddPerVertexAttr)*i; sliceVertexData[idx ] = unclippedSlice.getVertex(i).getValues()[0]; sliceVertexData[idx + 1] = unclippedSlice.getVertex(i).getValues()[1]; sliceVertexData[idx + 2] = unclippedSlice.getVertex(i).getValues()[2]; // set (standard) texture coordinates sliceVertexData[idx + 3] = texScale[0] * unclippedSlice.getVertex(i).getValues()[0] + texTranslate[0]; sliceVertexData[idx + 4] = texScale[1] * unclippedSlice.getVertex(i).getValues()[1] + texTranslate[1]; sliceVertexData[idx + 5] = texScale[2] * unclippedSlice.getVertex(i).getValues()[2] + texTranslate[2]; newPrimitive->vertices.push_back(&sliceVertexData[idx]); } clippedSlice.push_back(newPrimitive); return; } if(!hasTesselatorSupport) return; // render colored contours only (usefull for debugging) if(clipObjects->getDoContours()) { glDisable(GL_TEXTURE ); glDisable(GL_LIGHTING ); glBegin (GL_LINE_STRIP); { int col = 0; for(UInt32 i = 0; i < unclippedSlice.getVertexCount(); i++) { glColor3f(col % 3 == 0 ? 1.0f : 0.0f, col % 3 == 1 ? 1.0f : 0.0f, col % 3 == 2 ? 1.0f : 0.0f); col++; glVertex3fv(unclippedSlice.getVertex(i).getValues()); } } glEnd(); bool clipAwayOutside = clipObjects->getClipMode() == DVRClipObjects::Difference; for(UInt32 i = 0; i < clipObjects->count(); i++) { // get i-th clip object DVRClipGeometryPtr clipObject = clipObjects->get(i); // compute the contours of the triangles intersecting the // current slice const DVRTriangleList &contours = clipObject->getContours(dist2RefPlane, !clipAwayOutside, slicingNormal); if(!contours.empty()) { DVRTriangle *current; DVRTriangle *contourStart; // iterate over all contours DVRTriangleList::const_iterator contoursIt; for(contoursIt = contours.begin(); contoursIt != contours.end (); contoursIt++) { contourStart = current = *contoursIt; glBegin(GL_LINE_STRIP); { int col = 0; // iterate over all triangles in the current contour do { glColor3f(col % 3 == 0 ? 1.0f : 0.0f, col % 3 == 1 ? 1.0f : 0.0f, col % 3 == 2 ? 1.0f : 0.0f); col++; glVertex3dv(current->cutPoint); current = current->contourNeighbour; } while(current!= contourStart); } glEnd(); } } } glEnable(GL_TEXTURE ); glEnable(GL_LIGHTING); } else { // tesselate and render the clipped slices // set the slice normal for tesselation gluTessNormal(myTess, slicingNormal[0], slicingNormal[1], slicingNormal[2]); clippedSlice.clear(); gluTessBeginPolygon(myTess, &clippedSlice); // set the slice's base contour gluTessBeginContour(myTess); for(UInt32 i = 0; i < unclippedSlice.getVertexCount(); i++) { UInt32 idx = (6 + numAddPerVertexAttr) * i; sliceVertexData[idx ] = unclippedSlice.getVertex(i).getValues()[0]; sliceVertexData[idx + 1] = unclippedSlice.getVertex(i).getValues()[1]; sliceVertexData[idx + 2] = unclippedSlice.getVertex(i).getValues()[2]; // set (standard) texture coordinates sliceVertexData[idx + 3] = texScale[0] * unclippedSlice.getVertex(i).getValues()[0] + texTranslate[0]; sliceVertexData[idx + 4] = texScale[1] * unclippedSlice.getVertex(i).getValues()[1] + texTranslate[1]; sliceVertexData[idx + 5] = texScale[2] * unclippedSlice.getVertex(i).getValues()[2] + texTranslate[2]; gluTessVertex(myTess, &sliceVertexData[idx], &sliceVertexData[idx]); } gluTessEndContour(myTess); // set contours of clip objects if(clipObjects->getClipMode() != DVRClipObjects::Off) { // get clip mode bool clipAwayOutside = clipObjects->getClipMode() == DVRClipObjects::Difference; // add the contours of the intersections of the clip geometries // with the slice for(UInt32 i = 0; i < clipObjects->count(); i++) { // get i-th clip object DVRClipGeometryPtr clipObject = clipObjects->get(i); // compute the contours of the triangles intersecting // the current slice const DVRTriangleList &contours = clipObject->getContours( dist2RefPlane, !clipAwayOutside, slicingNormal); if(!contours.empty()) { DVRTriangle *current; DVRTriangle *contourStart; // iterate over all contours DVRTriangleList::const_iterator contoursIt; for(contoursIt = contours.begin(); contoursIt != contours.end (); contoursIt++) { contourStart = current = *contoursIt; // start new contour gluTessBeginContour(myTess); // iterate over all triangles in the current contour do { // set (standard) texture coordinates current->cutPoint[3] = texScale[0] * current->cutPoint[0] + texTranslate[0]; current->cutPoint[4] = texScale[1] * current->cutPoint[1] + texTranslate[1]; current->cutPoint[5] = texScale[2] * current->cutPoint[2] + texTranslate[2]; if(!current->cutPoint) std::cerr << "WTF: cutPoint is NULL" << std::endl; gluTessVertex(myTess, current->cutPoint, current->cutPoint); current = current->contourNeighbour; } while(current != contourStart); gluTessEndContour(myTess); } } } } gluTessEndPolygon(myTess); } }