Мультитекстурирование с помощью C# и ActiViz .NET

Я хочу использовать ActiViz .NET и C# для мультитекстурирования объекта, созданного из файла.obj.

Пока я знаю, как использовать текстуру с одной текстурой, у меня проблемы с несколькими текстурами. Основываясь на том, что я нашел в VTK GitHub, я начал писать код, но возникает проблема с методами SetBlendingMode и MapDataArrayToMultiTextureAttribute. Я использую SetBlendingMode, как это:

texture.SetBlendingMode(vtkTexture.VTKTextureBlendingMode.VTK_TEXTURE_BLENDING_MODE_REPLACE);

что приводит к:

The best overloaded method match for 'Kitware.VTK.vtkTexture.SetBlendingMode(int)' has some invalid arguments

С MapDataArrayToMultiTextureAttribute это выглядит так:

mapper.MapDataArrayToMultiTextureAttribute(vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_0, "TCoords", vtkDataObject.FIELD_ASSOCIATION, 0);

который заканчивается похожим сообщением:

The best overloaded method match for 'Kitware.VTK.vtkPolyDataMapper.MapDataArrayToMultiTextureAttribute(int, string, int, int)' has some invalid arguments

Весь код:

private void ReadOBJ(string path)
        {

            vtkTesting test = vtkTesting.New();

        // Varibles for obj file and texture
        string filePath = path;
        string texturePath0 = @"C:\Users\admin\Desktop\Fox-Skull-obj\Fox Skull_0.jpg";
        string texturePath1 = @"C:\Users\admin\Desktop\Fox-Skull-obj\Fox Skull_1.jpg";
        string texturePath2 = @"C:\Users\admin\Desktop\Fox-Skull-obj\Fox Skull_2.jpg";
        string texturePath3 = @"C:\Users\admin\Desktop\Fox-Skull-obj\Fox Skull_3.jpg";

        // Open jpeg file including texture
        vtkJPEGReader jpegReader = new vtkJPEGReader();
        jpegReader.SetFileName(texturePath0);
        jpegReader.Update();

        vtkJPEGReader jpegReader1 = new vtkJPEGReader();
        jpegReader1.SetFileName(texturePath1);
        jpegReader1.Update();
        vtkJPEGReader jpegReader2 = new vtkJPEGReader();
        jpegReader2.SetFileName(texturePath2);
        jpegReader2.Update();
        vtkJPEGReader jpegReader3 = new vtkJPEGReader();
        jpegReader3.SetFileName(texturePath3);
        jpegReader3.Update();

        // Open obj file
        vtkOBJReader reader = new vtkOBJReader();
        if (!File.Exists(filePath))
        {
            MessageBox.Show("Cannot read file \"" + filePath + "\"", "Error", MessageBoxButtons.OK);
            return;
        }
        reader.SetFileName(filePath);
        reader.Update();

        vtkTriangleFilter triangleFilter = vtkTriangleFilter.New();
        triangleFilter.SetInputConnection(reader.GetOutputPort());

        vtkStripper stripper = vtkStripper.New();
        stripper.SetInputConnection(triangleFilter.GetOutputPort());
        stripper.Update();

        vtkPolyData polydata = stripper.GetOutput();
        polydata.Register(null);
        polydata.GetPointData().SetNormals(null);

        vtkFloatArray TCoords = vtkFloatArray.New();
        TCoords.SetNumberOfComponents(2);
        TCoords.Allocate(8, 0);

        TCoords.InsertNextTuple2(0.0, 0.0);
        TCoords.InsertNextTuple2(1.0, 0.0);
        TCoords.InsertNextTuple2(0.0, 1.0);
        TCoords.InsertNextTuple2(1.0, 1.0);
        TCoords.SetName("TCoords");

        polydata.GetPointData().AddArray(TCoords);


        // Create texture
        vtkTexture texture = new vtkTexture();
        vtkTexture texture1 = new vtkTexture();
        vtkTexture texture2 = new vtkTexture();
        vtkTexture texture3 = new vtkTexture();
        texture.SetInputConnection(jpegReader.GetOutputPort());
        texture1.SetInputConnection(jpegReader1.GetOutputPort());
        texture2.SetInputConnection(jpegReader2.GetOutputPort());
        texture3.SetInputConnection(jpegReader3.GetOutputPort());

        texture.SetBlendingMode((int)vtkTexture.VTKTextureBlendingMode.VTK_TEXTURE_BLENDING_MODE_REPLACE);
        texture1.SetBlendingMode((int)vtkTexture.VTKTextureBlendingMode.VTK_TEXTURE_BLENDING_MODE_ADD);
        texture2.SetBlendingMode((int)vtkTexture.VTKTextureBlendingMode.VTK_TEXTURE_BLENDING_MODE_ADD);
        texture3.SetBlendingMode((int)vtkTexture.VTKTextureBlendingMode.VTK_TEXTURE_BLENDING_MODE_ADD);

        // Mapping textures


        vtkTextureMapToCylinder mapSphere = new vtkTextureMapToCylinder();
        mapSphere.SetInputConnection(reader.GetOutputPort());


        // Visualize           
        vtkPolyDataMapper mapper = vtkPolyDataMapper.New();           
        mapper.SetInput(polydata);

        // Get a reference to the renderwindow of our renderWindowControl1
        vtkRenderWindow renderWindow = renderWindowControl1.RenderWindow;
        // Renderer
        vtkRenderer renderer = renderWindow.GetRenderers().GetFirstRenderer();  

        vtkRenderWindowInteractor iren = vtkRenderWindowInteractor.New();
        iren.SetRenderWindow(renderWindow);

        // Create actor and add mapper with texture
        vtkActor actor = vtkActor.New();

        vtkOpenGLHardwareSupport hardware = vtkOpenGLRenderWindow.SafeDownCast(renderWindow).GetHardwareSupport();
        bool supported = hardware.GetSupportsMultiTexturing();
        int tu = 0;

        if (supported)
        {
            tu = hardware.GetNumberOfFixedTextureUnits();
        }
        if (supported && tu > 2)
        {
            mapper.MapDataArrayToMultiTextureAttribute((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_0, "TCoords", (int)vtkDataObject.FieldAssociations.FIELD_ASSOCIATION_POINTS, -1);
            mapper.MapDataArrayToMultiTextureAttribute((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_1, "TCoords", (int)vtkDataObject.FieldAssociations.FIELD_ASSOCIATION_POINTS, -1);
            mapper.MapDataArrayToMultiTextureAttribute((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_2, "TCoords", (int)vtkDataObject.FieldAssociations.FIELD_ASSOCIATION_POINTS, -1);
            mapper.MapDataArrayToMultiTextureAttribute((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_3, "TCoords", (int)vtkDataObject.FieldAssociations.FIELD_ASSOCIATION_POINTS, -1);              

            actor.GetProperty().SetTexture((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_0, texture);
            actor.GetProperty().SetTexture((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_1, texture1);
            actor.GetProperty().SetTexture((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_2, texture2);
            actor.GetProperty().SetTexture((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_3, texture3);

        }
        else
        {
            if (supported)
            {
                mapper.MapDataArrayToMultiTextureAttribute((int)vtkProperty.VTKTextureUnit.VTK_TEXTURE_UNIT_0, "TCoords", (int)vtkDataObject.AttributeTypes.POINT, 0);
            }
            actor.SetTexture(texture);
        }

        actor.SetMapper(mapper);
        renderWindow.AddRenderer(renderer);



        // Hide current actor
        renderer.RemoveAllViewProps();
        // Set background color
        renderer.SetBackground(0.3, 0.6, 0.3);
        // Add new actor to the renderer
        renderer.AddActor(actor);

        // Render
        renderWindow.Render();

        }

Кто-нибудь имеет опыт работы с мультитекстурой с C# и VTK и может мне помочь? Знаете ли вы какие-либо другие решения, которые могут мне помочь?

РЕДАКТИРОВАТЬ 01.12.2015

Благодаря ответу JohnnyQ я, вероятно, сделаю функции, упомянутые выше, работающими. Я говорю "вероятно", потому что сейчас, когда я запускаю код и выбираю файл.obj, программа перестает работать с одной из двух ошибок:An unhandled exception of type 'System.AccessViolationException' occurred in Kitware.VTK.dll с информацией о попытке чтения или записи защищенной памяти или программа просто останавливается с vshost32.exe stop working сообщение.

Я обновил код выше до актуальной версии. Любые предложения по-прежнему приветствуются.

1 ответ

Вы должны явным образом привести тип enum к целочисленному типу.

например

texture.SetBlendingMode((int)vtkTexture.VTKTextureBlendingMode.VTK_TEXTURE_BLENDING_MODE_REPLACE);
Другие вопросы по тегам