Мультитекстурирование с помощью 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);