20 #include <sofa/core/visual/VisualParams.h>
21 #include <vtkCellArray.h>
22 #include <vtkFloatArray.h>
23 #include <vtkImageData.h>
24 #include <vtkImageReader2.h>
25 #include <vtkImageReader2Factory.h>
26 #include <vtkPointData.h>
27 #include <vtkPolyData.h>
28 #include <vtkOpenGLTexture.h>
35 static bool isInitialized =
false;
45 GLenum error = glewInit();
49 MITK_ERROR(
"glewInit") << glewGetErrorString(error);
60 mitk::VtkModel::VtkModel()
62 m_BuffersWereCreated(false),
63 m_LastNumberOfVertices(0),
64 m_LastNumberOfTriangles(0),
65 m_LastNumberOfQuads(0),
68 m_VtkRenderer(nullptr),
73 mitk::VtkModel::~VtkModel()
75 if (m_Mode ==
OpenGL && m_BuffersWereCreated)
77 glDeleteBuffers(1, &m_IndexBuffer);
78 glDeleteBuffers(1, &m_VertexBuffer);
82 void mitk::VtkModel::CreateIndexBuffer()
86 glGenBuffers(1, &m_IndexBuffer);
88 else if (m_Mode == Surface)
93 this->InitIndexBuffer();
96 void mitk::VtkModel::CreateVertexBuffer()
100 glGenBuffers(1, &m_VertexBuffer);
102 else if (m_Mode == Surface)
109 this->InitVertexBuffer();
112 void mitk::VtkModel::DrawGroup(
int group,
bool transparent)
114 if (m_Mode == OpenGL)
116 this->DrawOpenGLGroup(group, transparent);
118 else if (m_Mode == Surface)
120 this->DrawSurfaceGroup(group, transparent);
124 void mitk::VtkModel::DrawOpenGLGroup(
int group,
bool)
126 using sofa::core::loader::Material;
127 using sofa::defaulttype::ResizableExtVector;
128 using sofa::defaulttype::Vec4f;
130 const VecCoord& vertices = this->getVertices();
131 const ResizableExtVector<Deriv>& normals = this->getVnormals();
132 const ResizableExtVector<Triangle>& triangles = this->getTriangles();
133 const ResizableExtVector<Quad>& quads = this->getQuads();
139 faceGroup.nbt = triangles.size();
140 faceGroup.nbq = quads.size();
144 faceGroup = groups.getValue()[group];
147 Material material = faceGroup.materialId != -1
148 ? materials.getValue()[faceGroup.materialId]
149 : this->material.getValue();
151 if (material.useTexture && material.activated)
153 m_Textures[faceGroup.materialId]->Load(m_VtkRenderer);
155 glEnable(GL_TEXTURE_2D);
156 glTexCoordPointer(2, GL_FLOAT, 0, reinterpret_cast<const GLvoid*>(vertices.size() *
sizeof(VecCoord::value_type) + normals.size() *
sizeof(Deriv)));
157 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
160 Vec4f ambient = material.useAmbient ? material.ambient : Vec4f();
161 Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f();
162 Vec4f specular = material.useSpecular ? material.specular : Vec4f();
163 Vec4f emissive = material.useEmissive ? material.emissive : Vec4f();
164 float shininess = material.useShininess ?
std::min(material.shininess, 128.0f) : 45.0f;
166 if (shininess == 0.0f)
172 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr());
173 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr());
174 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr());
175 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr());
176 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
178 if (faceGroup.nbt != 0)
179 glDrawElements(GL_TRIANGLES, faceGroup.nbt * 3, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid*>(faceGroup.tri0 *
sizeof(Triangle)));
181 if (faceGroup.nbq != 0)
182 glDrawElements(GL_QUADS, faceGroup.nbq * 4, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid*>(triangles.size() *
sizeof(Triangle) + faceGroup.quad0 *
sizeof(Quad)));
184 if (material.useTexture && material.activated)
186 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
187 glDisable(GL_TEXTURE_2D);
189 m_Textures[faceGroup.materialId]->PostRender(m_VtkRenderer);
193 void mitk::VtkModel::DrawSurfaceGroup(
int group,
bool)
195 m_PolyData->SetPoints(m_Points);
196 m_PolyData->SetPolys(m_Polys);
198 vtkPointData* pointData = m_PolyData->GetPointData();
200 pointData->SetNormals(m_Normals->GetSize() != 0
204 pointData->SetTCoords(m_TexCoords->GetSize() != 0
208 m_PolyData->Modified();
211 void mitk::VtkModel::DrawGroups(
bool transparent)
213 using sofa::core::objectmodel::Data;
214 using sofa::helper::ReadAccessor;
215 using sofa::helper::vector;
217 ReadAccessor<Data<vector<FaceGroup> > > groups = this->groups;
221 this->DrawGroup(-1, transparent);
225 int numGroups =
static_cast<int>(groups.size());
227 for (
int i = 0; i < numGroups; ++i)
228 this->DrawGroup(i, transparent);
232 void mitk::VtkModel::InitIndexBuffer()
234 using sofa::defaulttype::ResizableExtVector;
236 const ResizableExtVector<Triangle>& triangles = this->getTriangles();
237 const ResizableExtVector<Quad>& quads = this->getQuads();
239 if (m_Mode == OpenGL)
241 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
242 glBufferData(GL_ELEMENT_ARRAY_BUFFER, triangles.size() *
sizeof(Triangle) + quads.size() *
sizeof(Quad),
nullptr, GL_DYNAMIC_DRAW);
245 this->UpdateIndexBuffer();
248 void mitk::VtkModel::InitVertexBuffer()
250 using sofa::defaulttype::ResizableExtVector;
252 const VecCoord& vertices = this->getVertices();
253 const ResizableExtVector<Deriv> normals = this->getVnormals();
254 const VecTexCoord& texCoords = this->getVtexcoords();
256 if (m_Mode == OpenGL)
258 glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
259 glBufferData(GL_ARRAY_BUFFER, vertices.size() *
sizeof(VecCoord::value_type) + normals.size() *
sizeof(Deriv) + texCoords.size() *
sizeof(VecTexCoord::value_type),
nullptr, GL_DYNAMIC_DRAW);
261 else if (m_Mode == Surface)
263 m_Points->SetNumberOfPoints(vertices.size());
265 m_Normals->SetNumberOfComponents(3);
266 m_Normals->SetNumberOfTuples(normals.size());
268 m_TexCoords->SetNumberOfComponents(2);
269 m_TexCoords->SetNumberOfTuples(texCoords.size());
272 this->UpdateVertexBuffer();
277 using sofa::core::visual::DisplayFlags;
278 using sofa::defaulttype::ResizableExtVector;
280 if (m_Mode == OpenGL && !m_GlewIsInitialized)
286 if (m_GlewIsInitialized)
288 this->updateBuffers();
296 const DisplayFlags& displayFlags = vparams->displayFlags();
298 if (!displayFlags.getShowVisualModels())
301 if (m_BuffersWereCreated ==
false)
304 if (m_Mode == OpenGL)
306 glEnable(GL_LIGHTING);
307 glColor3f(1.0f, 1.0f, 1.0f);
308 glPolygonMode(GL_FRONT_AND_BACK, displayFlags.getShowWireFrame() ? GL_LINE : GL_FILL);
310 const VecCoord& vertices = this->getVertices();
312 glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
313 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
315 this->ValidateBoundBuffers();
317 glVertexPointer(3, GL_FLOAT, 0,
nullptr);
318 glNormalPointer(GL_FLOAT, 0, reinterpret_cast<const GLvoid*>(vertices.size() *
sizeof(VecCoord::value_type)));
319 glEnableClientState(GL_VERTEX_ARRAY);
320 glEnableClientState(GL_NORMAL_ARRAY);
323 this->DrawGroups(transparent);
325 if (m_Mode == OpenGL)
327 glDisableClientState(GL_NORMAL_ARRAY);
328 glDisableClientState(GL_VERTEX_ARRAY);
330 if (displayFlags.getShowWireFrame())
331 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
333 glDisable(GL_LIGHTING);
336 if (displayFlags.getShowNormals())
340 void mitk::VtkModel::DrawNormals()
342 using sofa::defaulttype::ResizableExtVector;
344 if (m_Mode == OpenGL)
346 const VecCoord& vertices = this->getVertices();
347 const ResizableExtVector<Deriv>& normals = this->getVnormals();
348 size_t numVertices = vertices.size();
353 for (
size_t i = 0; i < numVertices; ++i)
355 glVertex3fv(vertices[i].ptr());
356 normal = vertices[i] + normals[i];
357 glVertex3fv(normal.ptr());
366 using sofa::helper::system::DataRepository;
367 using sofa::helper::vector;
368 using sofa::core::loader::Material;
372 std::vector<unsigned int> materialIndices;
374 const vector<Material>& materials = this->materials.getValue();
375 unsigned int numMaterials = materials.size();
377 for (
unsigned int i = 0; i < numMaterials; ++i)
379 const Material& material = materials[i];
381 if (material.useTexture && material.activated)
382 materialIndices.push_back(i);
385 bool retValue =
true;
386 size_t numTextures = materialIndices.size();
388 for (
size_t i = 0; i < numTextures; ++i)
390 std::string
filename = materials[materialIndices[i]].textureFilename;
392 if (!DataRepository.findFile(filename))
394 MITK_ERROR(
"VtkModel") <<
"File \"" << filename <<
"\" not found!";
399 vtkSmartPointer<vtkImageReader2> imageReader = vtkSmartPointer<vtkImageReader2>::Take(vtkImageReader2Factory::CreateImageReader2(filename.c_str()));
401 if (imageReader ==
nullptr)
403 MITK_ERROR(
"VtkModel") <<
"File \"" << filename <<
"\" has unknown image format!";
408 imageReader->SetFileName(filename.c_str());
409 imageReader->UpdateWholeExtent();
412 texture->SetInputConnection(imageReader->GetOutputPort());
413 texture->InterpolateOn();
415 m_Textures.insert(std::make_pair(materialIndices[i], texture));
438 m_DataNode =
nullptr;
440 m_PolyData =
nullptr;
441 m_TexCoords =
nullptr;
448 if (m_Mode == OpenGL && m_BuffersWereCreated)
450 glDeleteBuffers(1, &m_IndexBuffer);
453 glDeleteBuffers(1, &m_VertexBuffer);
460 m_Surface->SetVtkPolyData(m_PolyData);
463 m_DataNode->SetName(name.getValue());
464 m_DataNode->SetData(m_Surface);
471 m_BuffersWereCreated =
false;
472 this->updateBuffers();
477 m_VtkRenderer = renderer;
482 using sofa::defaulttype::ResizableExtVector;
484 if (m_Mode == OpenGL && !m_GlewIsInitialized)
487 const VecCoord& vertices = this->getVertices();
488 const ResizableExtVector<Triangle>& triangles = this->getTriangles();
489 const ResizableExtVector<Quad>& quads = this->getQuads();
491 if (!m_BuffersWereCreated)
493 this->CreateVertexBuffer();
494 this->CreateIndexBuffer();
496 m_BuffersWereCreated =
true;
500 if (m_LastNumberOfVertices != vertices.size())
501 this->InitVertexBuffer();
503 this->UpdateVertexBuffer();
505 if (m_LastNumberOfTriangles != triangles.size() || m_LastNumberOfQuads != quads.size())
506 this->InitIndexBuffer();
508 this->UpdateIndexBuffer();
511 m_LastNumberOfVertices = vertices.size();
512 m_LastNumberOfTriangles = triangles.size();
513 m_LastNumberOfQuads = quads.size();
516 void mitk::VtkModel::UpdateIndexBuffer()
518 using sofa::defaulttype::ResizableExtVector;
520 const ResizableExtVector<Triangle>& triangles = this->getTriangles();
521 const ResizableExtVector<Quad>& quads = this->getQuads();
523 GLsizeiptr sizeOfTriangleIndices = triangles.size() *
sizeof(Triangle);
524 GLsizeiptr sizeOfQuadIndices = quads.size() *
sizeof(Quad);
526 if (m_Mode == OpenGL)
528 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
529 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeOfTriangleIndices, triangles.getData());
530 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sizeOfTriangleIndices, sizeOfQuadIndices, quads.getData());
532 else if (m_Mode == Surface)
534 m_Polys->Initialize();
536 if (!triangles.empty())
538 ResizableExtVector<Triangle>::const_iterator trianglesEnd = triangles.end();
540 for (ResizableExtVector<Triangle>::const_iterator it = triangles.begin(); it != trianglesEnd; ++it)
542 const Triangle& triangle = *it;
544 m_Polys->InsertNextCell(3);
545 m_Polys->InsertCellPoint(triangle[0]);
546 m_Polys->InsertCellPoint(triangle[1]);
547 m_Polys->InsertCellPoint(triangle[2]);
553 ResizableExtVector<Quad>::const_iterator quadsEnd = quads.end();
555 for (ResizableExtVector<Quad>::const_iterator it = quads.begin(); it != quadsEnd; ++it)
557 const Quad& quad = *it;
559 m_Polys->InsertNextCell(4);
560 m_Polys->InsertCellPoint(quad[0]);
561 m_Polys->InsertCellPoint(quad[1]);
562 m_Polys->InsertCellPoint(quad[2]);
563 m_Polys->InsertCellPoint(quad[3]);
569 void mitk::VtkModel::UpdateVertexBuffer()
571 using sofa::defaulttype::ResizableExtVector;
573 const VecCoord& vertices = this->getVertices();
574 const ResizableExtVector<Deriv> normals = this->getVnormals();
575 const VecTexCoord& texCoords = this->getVtexcoords();
577 if (m_Mode == OpenGL)
579 GLsizeiptr sizeOfVertices = vertices.size() *
sizeof(VecCoord::value_type);
580 GLsizeiptr sizeOfNormals = normals.size() *
sizeof(Deriv);
582 glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
583 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeOfVertices, vertices.getData());
584 glBufferSubData(GL_ARRAY_BUFFER, sizeOfVertices, sizeOfNormals, normals.getData());
586 if (!m_Textures.empty())
588 GLsizeiptr sizeOfTexCoords = texCoords.size() *
sizeof(VecTexCoord::value_type);
589 glBufferSubData(GL_ARRAY_BUFFER, sizeOfVertices + sizeOfNormals, sizeOfTexCoords, texCoords.getData());
592 else if (m_Mode == Surface)
594 size_t numPoints = vertices.size();
596 for (
size_t i = 0; i < numPoints; ++i)
597 m_Points->SetPoint(i, vertices[i].elems);
599 if (!normals.empty())
601 size_t numNormals = normals.size();
603 for (
size_t i = 0; i < numNormals; ++i)
604 m_Normals->SetTuple(i, normals[i].elems);
607 if (!texCoords.empty())
609 size_t numTexCoords = texCoords.size();
611 for (
size_t i = 0; i < numTexCoords; ++i)
612 m_TexCoords->SetTuple(i, normals[i].elems);
617 void mitk::VtkModel::ValidateBoundBuffers()
619 if (m_Mode != OpenGL)
622 GLint indexBufferSize;
623 glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &indexBufferSize);
625 if (indexBufferSize == 0)
627 glDeleteBuffers(1, &m_IndexBuffer);
628 this->CreateIndexBuffer();
630 glDeleteBuffers(1, &m_VertexBuffer);
631 this->CreateVertexBuffer();
Class for storing surfaces (vtkPolyData).
bool loadTextures() override
void updateBuffers() override
void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material &material)
static RenderingManager * GetInstance()
static const std::string filename
void SetVtkRenderer(vtkRenderer *renderer)
DataNode::Pointer GetDataNode() const
void internalDraw(const sofa::core::visual::VisualParams *vparams, bool transparent) override
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.