示例#1
0
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);
    }
}