Quantcast

cleaning polydata precludes computing curvatures

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

cleaning polydata precludes computing curvatures

Lane Phillips-2
I have a 3DS model and I want to do analysis of the surface curvature.
I use a vtk3DSImporter to load the model and I notice that the model is
sliced into multiple meshes, so I take the vtkPolyData from each mesh
and send it through a vtkCurvatures and, magically, VTK displays the
curvature as color on the surface, and I can spin the model at
interactive rates.

I don't want to deal with multiple meshes, so I add each vtkPolyData to
a vtkAppendPolyData object, and send the output of that through the
vtkCurvatures object.  VTK still displays the curvatures on the surface,
but now it's extremely slow to rotate.  Maybe the slices cached better?
  However, speed is not my concern right now...

Now I have all the meshes in one vtkPolyData, but I assume they are not
contiguous yet, so I run the output of the vtkAppendPolyData through a
vtkCleanPolyData, hoping this will merge duplicate points and stitch the
meshes together.  I send the output of vtkCleanPolyData through
vtkCurvatures, but now the surface is rendered in one color.

So my question is, what information is needed by vtkCurvatures that is
getting destroyed by vtkCleanPolyData?

I'm attaching my code; sorry it's a mess.  The important lines are 81
through 127.

Thanks,
Lane


// Based on sample code from Kitware.
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkPolyDataNormals.h>
#include <vtk3DSImporter.h>
#include <vtkCurvatures.h>
#include <vtkSmoothPolyDataFilter.h>
#include <vtkJPEGReader.h>
#include <vtkTexture.h>
#include <vtkTextureMapToPlane.h>
#include <vtkTransformTextureCoords.h>
#include <vtkTriangleFilter.h>
#include <vtkFeatureEdges.h>
#include <vtkCommand.h>
#include <vtkPNGWriter.h>
#include <vtkWindowToImageFilter.h>
#include <vtkAppendPolyData.h>
#include <vtkCleanPolyData.h>
#include <vector>

// TODO need to interactively choose the file
#define MODEL_PREFIX "../../models/3ds/MDH-150"
// TODO need to interactively toggle smoothing?
//#define USE_SMOOTHING
#define SMOOTHING_ITERATIONS 1000

// vtkCommand to takes the snapshot of the renderWindow
// Press 'u' on the renWin to save the snapshot

class vtkSnapshotCallback : public vtkCommand {
public:
        static vtkSnapshotCallback *New() {
                return new vtkSnapshotCallback;
        }
       
        virtual void Execute(vtkObject *caller, unsigned long, void*) {
                vtkRenderWindowInteractor *rwi = reinterpret_cast<vtkRenderWindowInteractor*>(caller);
                vtkPNGWriter *writer = vtkPNGWriter::New();
                vtkWindowToImageFilter *w2iFilter = vtkWindowToImageFilter::New();

                w2iFilter->SetInput(rwi->GetRenderWindow());
                writer->SetInput(w2iFilter->GetOutput());
                std::string prefix(MODEL_PREFIX);
                std::string snapshotFile = prefix + "_snapshot.png";
                writer->SetFileName(snapshotFile.c_str());
                writer->Write();
        }
};


int main(int argc, char **argv)
{
        std::string prefix(MODEL_PREFIX);
        std::string modelFile = prefix + ".3ds";
        std::string textureFile = prefix + ".jpg";
       
        // Create the renderer, the render window, and the interactor. The renderer
        // draws into the render window, the interactor enables mouse- and
        // keyboard-based interaction with the data within the render window.
       
        vtkRenderer *aRenderer = vtkRenderer::New();
        vtkRenderWindow *renWin = vtkRenderWindow::New();
        renWin->AddRenderer(aRenderer);
        vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
        iren->SetRenderWindow(renWin);

        vtk3DSImporter* importer = vtk3DSImporter::New();
        // Change the file name to something you have on your system.
        // TODO We will need to make this more user-friendly.
        importer->SetFileName(modelFile.c_str());
        importer->ComputeNormalsOn();
        importer->Update();
        importer->Read();
       
        vtkAppendPolyData* wholeMesh = vtkAppendPolyData::New();
        // The stone tool models seem to consist of multiple meshes,
        // I hope this is not a problem.
        vtk3DSMesh* mesh = importer->MeshList;
        while (mesh) {
                wholeMesh->AddInput(mesh->aPolyData);
                // Next mesh in a linked list
                mesh = (vtk3DSMesh*)mesh->next;
        }
        // remove redundant points
        vtkCleanPolyData* cleaner = vtkCleanPolyData::New();
        cleaner->SetInput(wholeMesh->GetOutput());
        cleaner->PointMergingOn();
        cleaner->SetTolerance(0.0);
        cleaner->ConvertLinesToPointsOff ();
        cleaner->ConvertPolysToLinesOff ();
        cleaner->ConvertStripsToPolysOff ();
// vtkPolyDataNormals* normals = vtkPolyDataNormals::New();
// normals->SetInput(cleaner->GetOutput());
// normals->SplittingOn();
// normals->ComputeCellNormalsOn();

        //Reading the JPEG file and creating texture object
        vtkJPEGReader* jpgReader = vtkJPEGReader::New();
        jpgReader->SetFileName(textureFile.c_str());
        jpgReader->ReleaseDataFlagOn();
        vtkTexture* texture = vtkTexture::New();
        texture->SetInputConnection(jpgReader->GetOutputPort());
        texture->InterpolateOff();
        texture->RepeatOn();
        texture->ReleaseDataFlagOn();
        jpgReader->Delete();

// Code to smooth the data.
#if 1
        vtkCurvatures* curve = vtkCurvatures::New();
#ifdef USE_SMOOTHING
        vtkSmoothPolyDataFilter* smoother = vtkSmoothPolyDataFilter::New();
        smoother->SetInput(cleaner->GetOutput());
        smoother->SetNumberOfIterations(SMOOTHING_ITERATIONS);
        curve->SetInput(smoother->GetOutput());
#else
        curve->SetInput(cleaner->GetOutput());
#endif
        //curve->SetCurvatureTypeToGaussian ();
        //curve->SetCurvatureTypeToMean ();
        curve->SetCurvatureTypeToMaximum ();
        //curve->SetCurvatureTypeToMinimum ();

        // Create a mapper and an actor for each mesh
        // TODO I think we are going to want to combine meshes into one, don't know how hard that will be.
        vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();

        mapper->SetInput(curve->GetOutput());
        vtkActor* actor = vtkActor::New();
        actor->SetMapper(mapper);
        aRenderer->AddActor(actor);
#endif

// Code to map texture on to the 3D object
#if 0
                vtkTextureMapToPlane* tMapper = vtkTextureMapToPlane::New();
                vtkPolyDataNormals* normals = vtkPolyDataNormals::New();
                vtkTransformTextureCoords* transform = vtkTransformTextureCoords::New();
                normals = mesh->aNormals;

                tMapper->SetInputConnection(normals->GetOutputPort());
                transform->SetInput(tMapper->GetOutput());

                vtkPolyDataMapper* textureMapper = vtkPolyDataMapper::New();
                textureMapper->SetInputConnection(transform->GetOutputPort());
               
                vtkActor* textureActor = vtkActor::New();
                textureActor->SetMapper(textureMapper);
                textureActor->SetTexture(texture);

                aRenderer->AddActor(textureActor);
#endif

#if 0
                vtkTriangleFilter* triangleFilter = vtkTriangleFilter::New();
                vtkPolyDataNormals* normalData = vtkPolyDataNormals::New();
                normalData = mesh->aNormals;

                triangleFilter->SetInputConnection(normalData->GetOutputPort());

                vtkFeatureEdges* edges = vtkFeatureEdges::New();
                //edges->SetInputConnection(triangleFilter->GetOutputPort());
                edges->SetInputConnection(normalData->GetOutputPort());
                edges->ColoringOff();
// edges->FeatureEdgesOn();
                edges->SetFeatureAngle(15);
                //edges->BoundaryEdgesOn();
                //edges->ManifoldEdgesOn();
                //edges->NonManifoldEdgesOn();

                vtkPolyDataMapper* edgemapper = vtkPolyDataMapper::New();
                edgemapper->SetInputConnection(edges->GetOutputPort());
                edgemapper->SetResolveCoincidentTopologyToPolygonOffset();

                vtkActor* edgeActor = vtkActor::New();
                edgeActor->SetMapper(edgemapper);
                edgeActor->GetProperty()->SetColor(0,0,0);
                edgeActor->GetProperty()->SetLineStipplePattern(4369);
                edgeActor->VisibilityOn();
               
                aRenderer->AddActor(edgeActor);
#endif

        // It is convenient to create an initial view of the data. The FocalPoint
        // and Position form a vector direction. Later on (ResetCamera() method)
        // this vector is used to position the camera to look at the data in
        // this direction.
        vtkCamera *aCamera = vtkCamera::New();
        aCamera->SetViewUp(0, 0, -1);
        aCamera->SetPosition(0, 1, 0);
        aCamera->SetFocalPoint(0, 0, 0);
        aCamera->ComputeViewPlaneNormal();

        // Actors are added to the renderer. An initial camera view is created.
        // The Dolly() method moves the camera towards the FocalPoint,
        // thereby enlarging the image.
        aRenderer->SetActiveCamera(aCamera);
        aRenderer->ResetCamera();
        aCamera->Dolly(1.5);

        // Set a background color for the renderer and set the size of the
        // render window (expressed in pixels).
        aRenderer->SetBackground(1, 1, 1);
        renWin->SetSize(640, 480);

        // Note that when camera movement occurs (as it does in the Dolly()
        // method), the clipping planes often need adjusting. Clipping planes
        // consist of two planes: near and far along the view direction. The
        // near plane clips out objects in front of the plane; the far plane
        // clips out objects behind the plane. This way only what is drawn
        // between the planes is actually rendered.
        aRenderer->ResetCameraClippingRange();

        //callback to snapshot of renWin
        //press 'u' on the renWin to save the snapshot
        vtkSnapshotCallback *snapshot = vtkSnapshotCallback::New();
        iren->AddObserver(vtkCommand::UserEvent, snapshot);

        // Initialize the event loop and then start it.
        iren->Initialize();
        iren->Start();

        // It is important to delete all objects created previously to prevent
        // memory leaks. In this case, since the program is on its way to
        // exiting, it is not so important. But in applications it is
        // essential.

#ifdef USE_SMOOTHING
        smoother->Delete();
#endif
        curve->Delete();
        actor->Delete();
        mapper->Delete();

       
        snapshot->Delete();
        texture->Delete();
        aCamera->Delete();
        iren->Delete();
        renWin->Delete();
        aRenderer->Delete();
        importer->Delete();

        return 0;
}


_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.vtk.org/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: cleaning polydata precludes computing curvatures

Vidyadhar-2
Hi
In all probability the cell and point normals are lost. 3DS meshes have both and are imported by the importer. Clean may be removing them. Try using vtkPolyDataNormals between clean and curvature. Set it up to compute both point and cell normals. Compare the result with that for slices. It is possible that vertex order in some cells gets changed in the pipeline (doubt it) in which case enable auto-orient normals.
HTH
Vidyadhar

On Mon, Mar 30, 2009 at 10:16 PM, Lane Phillips <[hidden email]> wrote:
I have a 3DS model and I want to do analysis of the surface curvature. I use a vtk3DSImporter to load the model and I notice that the model is sliced into multiple meshes, so I take the vtkPolyData from each mesh and send it through a vtkCurvatures and, magically, VTK displays the curvature as color on the surface, and I can spin the model at interactive rates.

I don't want to deal with multiple meshes, so I add each vtkPolyData to a vtkAppendPolyData object, and send the output of that through the vtkCurvatures object.  VTK still displays the curvatures on the surface, but now it's extremely slow to rotate.  Maybe the slices cached better?  However, speed is not my concern right now...

Now I have all the meshes in one vtkPolyData, but I assume they are not contiguous yet, so I run the output of the vtkAppendPolyData through a vtkCleanPolyData, hoping this will merge duplicate points and stitch the meshes together.  I send the output of vtkCleanPolyData through vtkCurvatures, but now the surface is rendered in one color.

So my question is, what information is needed by vtkCurvatures that is getting destroyed by vtkCleanPolyData?

I'm attaching my code; sorry it's a mess.  The important lines are 81 through 127.

Thanks,
Lane

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.vtk.org/mailman/listinfo/vtkusers



_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.vtk.org/mailman/listinfo/vtkusers
Loading...