From 9d969758981b91e98d92bb34a4ddf2f93605b2e2 Mon Sep 17 00:00:00 2001
From: Marc-Alexandre Espiaut <76531574+malespiaut@users.noreply.github.com>
Date: Mon, 27 May 2024 11:02:29 +0200
Subject: [PATCH 1/5] Adding preliminary Quake1 MDL plugin.

---
 plugins/native/module/CMakeLists.txt        |   1 +
 plugins/native/module/vtkQuakeMDLReader.cxx | 161 ++++++++++++++++++++
 plugins/native/module/vtkQuakeMDLReader.h   |  35 +++++
 3 files changed, 197 insertions(+)
 create mode 100644 plugins/native/module/vtkQuakeMDLReader.cxx
 create mode 100644 plugins/native/module/vtkQuakeMDLReader.h

diff --git a/plugins/native/module/CMakeLists.txt b/plugins/native/module/CMakeLists.txt
index 8b65c33501..2ffb871e60 100644
--- a/plugins/native/module/CMakeLists.txt
+++ b/plugins/native/module/CMakeLists.txt
@@ -1,5 +1,6 @@
 set(classes
   vtkF3DSplatReader
+  vtkQuakeMDLReader
   )
 
 set(_no_install "")
diff --git a/plugins/native/module/vtkQuakeMDLReader.cxx b/plugins/native/module/vtkQuakeMDLReader.cxx
new file mode 100644
index 0000000000..daa5d5e419
--- /dev/null
+++ b/plugins/native/module/vtkQuakeMDLReader.cxx
@@ -0,0 +1,161 @@
+#include "vtkQuakeMDLReader.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCommand.h>
+#include <vtkDemandDrivenPipeline.h>
+#include <vtkFloatArray.h>
+#include <vtkIdTypeArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkNew.h>
+#include <vtkPointData.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkUnsignedCharArray.h>
+
+//----------------------------------------------------------------------------
+vtkStandardNewMacro(vtkQuakeMDLReader);
+
+//----------------------------------------------------------------------------
+vtkQuakeMDLReader::vtkQuakeMDLReader()
+{
+  this->SetNumberOfInputPorts(0);
+}
+
+//----------------------------------------------------------------------------
+int vtkQuakeMDLReader::RequestData(
+  vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector)
+{
+  vtkPolyData* output = vtkPolyData::GetData(outputVector);
+
+  std::ifstream inputStream(this->FileName, std::ios::binary);
+
+  std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(inputStream), {});
+
+  //??? What's a “splat”???
+  constexpr size_t splatSize = 32;
+
+  //??? What is nbSplats???
+  size_t nbSplats = buffer.size() / splatSize;
+
+  // identity ("IDPO"): 4 chars (4 bytes)
+  vtkNew<vtkCharArray> IDPOArray;
+  IDPOArray->SetNumberOfComponents(4);
+  IDPOArray->SetNumberOfTuples(nbSplats);
+  IDPOArray->SetName("identity");
+
+  // version: 1 int (4 bytes)
+  vtkNew<vtkIntArray> version;
+  version->SetNumberOfComponents(1);
+  version->SetNumberOfTuples(nbSplats);
+  version->SetName("version");
+
+  //====================================
+
+  // scaling factor: 3 floats (12 bytes)
+  vtkNew<vtkFloatArray> scalingFactor;
+  scalingFactor->SetNumberOfComponents(3);
+  scalingFactor->SetNumberOfTuples(nbSplats);
+  scalingFactor->SetName("scaling factor");
+
+  // translation vector: 3 floats (12 bytes)
+  vtkNew<vtkFloatArray> translationVector;
+  translationVector->SetNumberOfComponents(3);
+  translationVector->SetNumberOfTuples(nbSplats);
+  translationVector->SetName("translation vector");
+
+  // bounding radius: 1 float (4 bytes)
+  vtkNew<vtkFloatArray> boundingRadius;
+  boundingRadius->SetNumberOfComponents(1);
+  boundingRadius->SetNumberOfTuples(nbSplats);
+  boundingRadius->SetName("bounding radius");
+
+  // eye position: 3 floats (12 bytes)
+  vtkNew<vtkFloatArray> eyePosition;
+  eyePosition->SetNumberOfComponents(3);
+  eyePosition->SetNumberOfTuples(nbSplats);
+  eyePosition->SetName("eye position");
+
+  //====================================
+  
+  // number of textures: 1 int (4 bytes)
+  vtkNew<vtkIntArray> texturesNum;
+  texturesNum->SetNumberOfComponents(1);
+  texturesNum->SetNumberOfTuples(nbSplats);
+  texturesNum->SetName("number of textures");
+  
+  // texture width: 1 int (4 bytes)
+  vtkNew<vtkIntArray> textureWidth;
+  textureWidth->SetNumberOfComponents(1);
+  texturesWidth->SetNumberOfTuples(nbSplats);
+  textureWidth->SetName("texture width");
+  
+  // texture height: 1 int (4 bytes)
+  vtkNew<vtkIntArray> textureHeight;
+  textureHeight->SetNumberOfComponents(1);
+  textureHeight->SetNumberOfTuples(nbSplats);
+  textureHeight->SetName("texture height");
+
+  //====================================
+
+  // number of vertices: 1 int (4 bytes)
+  vtkNew<vtkIntArray> verticesNum;
+  verticesNum->SetNumberOfComponents(1);
+  verticesNum->SetNumberOfTuples(nbSplats);
+  verticesNum->SetName("number of vertices");
+
+  // number of triangles: 1 int (4 bytes)
+  vtkNew<vtkIntArray> trianglesNum;
+  trianglesNum->SetNumberOfComponents(1);
+  trianglesNum->SetNumberOfTuples(nbSplats);
+  trianglesNum->SetName("number of triangles");
+
+  // number of frames: 1 int (4 bytes)
+  vtkNew<vtkArray> framesNum;
+  framesNum->SetNumberOfComponents(1);
+  framesNum->SetNumberOfTuples(nbSplats);
+  framesNum->SetName("number of frames");
+
+  //====================================
+
+  // sync type (0: synchron, 1: random): 1 int (4 bytes)
+  vtkNew<vtkIntArray> syncType;
+  syncType->SetNumberOfComponents(1);
+  syncType->SetNumberOfTuples(nbSplats);
+  syncType->SetName("sync type");
+
+  // state flags: 1 int (4 bytes)
+  vtkNew<vtkIntArray> stateFlags;
+  stateFlags->SetNumberOfComponents(1);
+  stateFlags->SetNumberOfTuples(nbSplats);
+  stateFlags->SetName("state flags");
+
+  //====================================
+
+  // position: 3 floats (12 bytes)
+  vtkNew<vtkFloatArray> position;
+  position->SetNumberOfComponents(3);
+  position->SetNumberOfTuples(nbSplats);
+  position->SetName("position");
+
+  // scale: 3 floats (12 bytes)
+  vtkNew<vtkFloatArray> scale;
+  scale->SetNumberOfComponents(3);
+  scale->SetNumberOfTuples(nbSplats);
+  scale->SetName("scale");
+
+  // rotation: 4 chars (4 bytes)
+  vtkNew<vtkCharArray> rotation;
+  rotation->SetNumberOfComponents(4);
+  rotation->SetNumberOfTuples(nbSplats);
+  rotation->SetName("rotation");
+
+  // color+opacity: 4 chars (4 bytes)
+  vtkNew<vtkCharArray> colorAndOpacity;
+  colorAndOpacity->SetNumberOfComponents(4);
+  colorAndOpacity->SetNumberOfTuples(nbSplats);
+  colorAndOpacity->SetName("color and opacity");
+
+  return 1;
+}
diff --git a/plugins/native/module/vtkQuakeMDLReader.h b/plugins/native/module/vtkQuakeMDLReader.h
new file mode 100644
index 0000000000..cee1a4c596
--- /dev/null
+++ b/plugins/native/module/vtkQuakeMDLReader.h
@@ -0,0 +1,35 @@
+/**
+ * @class   vtkQuakeMDLReader
+ * @brief   VTK Reader for Quake 1 models in binary .mdl file format
+ */
+
+#ifndef vtkQuakeMDLReader_h
+#define vtkQuakeMDLReader_h
+
+#include <vtkPolyDataAlgorithm.h>
+
+class vtkQuakeMDLReader : public vtkPolyDataAlgorithm
+{
+public:
+  static vtkQuakeMDLReader* New();
+  vtkTypeMacro(vtkQuakeMDLReader, vtkPolyDataAlgorithm);
+
+  /**
+   * Set the file name.
+   */
+  vtkSetMacro(FileName, std::string);
+
+protected:
+  vtkQuakeMDLReader();
+  ~vtkQuakeMDLReader() override = default;
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+
+private:
+  vtkQuakeMDLReader(const vtkQuakeMDLReader&) = delete;
+  void operator=(const vtkQuakeMDLReader&) = delete;
+
+  std::string FileName;
+};
+
+#endif

From 31e502a5441094f8e54f8d38755b6dea14e83fe5 Mon Sep 17 00:00:00 2001
From: Marc-Alexandre Espiaut <76531574+malespiaut@users.noreply.github.com>
Date: Mon, 27 May 2024 11:10:14 +0200
Subject: [PATCH 2/5] Fixing some vector types error in vtkQuakeMDLReader.

---
 plugins/native/module/vtkQuakeMDLReader.cxx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/plugins/native/module/vtkQuakeMDLReader.cxx b/plugins/native/module/vtkQuakeMDLReader.cxx
index daa5d5e419..94a407ee74 100644
--- a/plugins/native/module/vtkQuakeMDLReader.cxx
+++ b/plugins/native/module/vtkQuakeMDLReader.cxx
@@ -40,7 +40,7 @@ int vtkQuakeMDLReader::RequestData(
   size_t nbSplats = buffer.size() / splatSize;
 
   // identity ("IDPO"): 4 chars (4 bytes)
-  vtkNew<vtkCharArray> IDPOArray;
+  vtkNew<vtkUnsignedCharArray> IDPOArray;
   IDPOArray->SetNumberOfComponents(4);
   IDPOArray->SetNumberOfTuples(nbSplats);
   IDPOArray->SetName("identity");
@@ -112,7 +112,7 @@ int vtkQuakeMDLReader::RequestData(
   trianglesNum->SetName("number of triangles");
 
   // number of frames: 1 int (4 bytes)
-  vtkNew<vtkArray> framesNum;
+  vtkNew<vtkIntArray> framesNum;
   framesNum->SetNumberOfComponents(1);
   framesNum->SetNumberOfTuples(nbSplats);
   framesNum->SetName("number of frames");
@@ -146,13 +146,13 @@ int vtkQuakeMDLReader::RequestData(
   scale->SetName("scale");
 
   // rotation: 4 chars (4 bytes)
-  vtkNew<vtkCharArray> rotation;
+  vtkNew<vtkUnsignedCharArray> rotation;
   rotation->SetNumberOfComponents(4);
   rotation->SetNumberOfTuples(nbSplats);
   rotation->SetName("rotation");
 
   // color+opacity: 4 chars (4 bytes)
-  vtkNew<vtkCharArray> colorAndOpacity;
+  vtkNew<vtkUnsignedCharArray> colorAndOpacity;
   colorAndOpacity->SetNumberOfComponents(4);
   colorAndOpacity->SetNumberOfTuples(nbSplats);
   colorAndOpacity->SetName("color and opacity");

From 614385b8351a1f19dae9445e099d12209442b4be Mon Sep 17 00:00:00 2001
From: Marc-Alexandre Espiaut <76531574+malespiaut@users.noreply.github.com>
Date: Mon, 27 May 2024 11:12:07 +0200
Subject: [PATCH 3/5] Fixing some formatting error (whitespaces) in
 vtkQuakeMDLReader.

---
 plugins/native/module/vtkQuakeMDLReader.cxx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/native/module/vtkQuakeMDLReader.cxx b/plugins/native/module/vtkQuakeMDLReader.cxx
index 94a407ee74..03f2a1fc0b 100644
--- a/plugins/native/module/vtkQuakeMDLReader.cxx
+++ b/plugins/native/module/vtkQuakeMDLReader.cxx
@@ -78,19 +78,19 @@ int vtkQuakeMDLReader::RequestData(
   eyePosition->SetName("eye position");
 
   //====================================
-  
+
   // number of textures: 1 int (4 bytes)
   vtkNew<vtkIntArray> texturesNum;
   texturesNum->SetNumberOfComponents(1);
   texturesNum->SetNumberOfTuples(nbSplats);
   texturesNum->SetName("number of textures");
-  
+
   // texture width: 1 int (4 bytes)
   vtkNew<vtkIntArray> textureWidth;
   textureWidth->SetNumberOfComponents(1);
   texturesWidth->SetNumberOfTuples(nbSplats);
   textureWidth->SetName("texture width");
-  
+
   // texture height: 1 int (4 bytes)
   vtkNew<vtkIntArray> textureHeight;
   textureHeight->SetNumberOfComponents(1);

From 802a5ef8928801ca544c12c4b7bb033cb27683d9 Mon Sep 17 00:00:00 2001
From: Marc-Alexandre Espiaut <76531574+malespiaut@users.noreply.github.com>
Date: Mon, 27 May 2024 11:13:13 +0200
Subject: [PATCH 4/5] Fixing typo in vtkQuakeMDLReader.

---
 plugins/native/module/vtkQuakeMDLReader.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/plugins/native/module/vtkQuakeMDLReader.cxx b/plugins/native/module/vtkQuakeMDLReader.cxx
index 03f2a1fc0b..aa36a061f7 100644
--- a/plugins/native/module/vtkQuakeMDLReader.cxx
+++ b/plugins/native/module/vtkQuakeMDLReader.cxx
@@ -88,7 +88,7 @@ int vtkQuakeMDLReader::RequestData(
   // texture width: 1 int (4 bytes)
   vtkNew<vtkIntArray> textureWidth;
   textureWidth->SetNumberOfComponents(1);
-  texturesWidth->SetNumberOfTuples(nbSplats);
+  textureWidth->SetNumberOfTuples(nbSplats);
   textureWidth->SetName("texture width");
 
   // texture height: 1 int (4 bytes)

From bccc1268de860e98dfd64c27373be40073ee5d80 Mon Sep 17 00:00:00 2001
From: Marc-Alexandre Espiaut <76531574+malespiaut@users.noreply.github.com>
Date: Sun, 2 Jun 2024 12:43:26 +0200
Subject: [PATCH 5/5] Cleaning out unnecessary code.

---
 plugins/native/module/vtkQuakeMDLReader.cxx | 26 ---------------------
 1 file changed, 26 deletions(-)

diff --git a/plugins/native/module/vtkQuakeMDLReader.cxx b/plugins/native/module/vtkQuakeMDLReader.cxx
index aa36a061f7..15ff7d4a70 100644
--- a/plugins/native/module/vtkQuakeMDLReader.cxx
+++ b/plugins/native/module/vtkQuakeMDLReader.cxx
@@ -31,24 +31,14 @@ int vtkQuakeMDLReader::RequestData(
 
   std::ifstream inputStream(this->FileName, std::ios::binary);
 
-  std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(inputStream), {});
-
-  //??? What's a “splat”???
-  constexpr size_t splatSize = 32;
-
-  //??? What is nbSplats???
-  size_t nbSplats = buffer.size() / splatSize;
-
   // identity ("IDPO"): 4 chars (4 bytes)
   vtkNew<vtkUnsignedCharArray> IDPOArray;
   IDPOArray->SetNumberOfComponents(4);
-  IDPOArray->SetNumberOfTuples(nbSplats);
   IDPOArray->SetName("identity");
 
   // version: 1 int (4 bytes)
   vtkNew<vtkIntArray> version;
   version->SetNumberOfComponents(1);
-  version->SetNumberOfTuples(nbSplats);
   version->SetName("version");
 
   //====================================
@@ -56,25 +46,21 @@ int vtkQuakeMDLReader::RequestData(
   // scaling factor: 3 floats (12 bytes)
   vtkNew<vtkFloatArray> scalingFactor;
   scalingFactor->SetNumberOfComponents(3);
-  scalingFactor->SetNumberOfTuples(nbSplats);
   scalingFactor->SetName("scaling factor");
 
   // translation vector: 3 floats (12 bytes)
   vtkNew<vtkFloatArray> translationVector;
   translationVector->SetNumberOfComponents(3);
-  translationVector->SetNumberOfTuples(nbSplats);
   translationVector->SetName("translation vector");
 
   // bounding radius: 1 float (4 bytes)
   vtkNew<vtkFloatArray> boundingRadius;
   boundingRadius->SetNumberOfComponents(1);
-  boundingRadius->SetNumberOfTuples(nbSplats);
   boundingRadius->SetName("bounding radius");
 
   // eye position: 3 floats (12 bytes)
   vtkNew<vtkFloatArray> eyePosition;
   eyePosition->SetNumberOfComponents(3);
-  eyePosition->SetNumberOfTuples(nbSplats);
   eyePosition->SetName("eye position");
 
   //====================================
@@ -82,19 +68,16 @@ int vtkQuakeMDLReader::RequestData(
   // number of textures: 1 int (4 bytes)
   vtkNew<vtkIntArray> texturesNum;
   texturesNum->SetNumberOfComponents(1);
-  texturesNum->SetNumberOfTuples(nbSplats);
   texturesNum->SetName("number of textures");
 
   // texture width: 1 int (4 bytes)
   vtkNew<vtkIntArray> textureWidth;
   textureWidth->SetNumberOfComponents(1);
-  textureWidth->SetNumberOfTuples(nbSplats);
   textureWidth->SetName("texture width");
 
   // texture height: 1 int (4 bytes)
   vtkNew<vtkIntArray> textureHeight;
   textureHeight->SetNumberOfComponents(1);
-  textureHeight->SetNumberOfTuples(nbSplats);
   textureHeight->SetName("texture height");
 
   //====================================
@@ -102,19 +85,16 @@ int vtkQuakeMDLReader::RequestData(
   // number of vertices: 1 int (4 bytes)
   vtkNew<vtkIntArray> verticesNum;
   verticesNum->SetNumberOfComponents(1);
-  verticesNum->SetNumberOfTuples(nbSplats);
   verticesNum->SetName("number of vertices");
 
   // number of triangles: 1 int (4 bytes)
   vtkNew<vtkIntArray> trianglesNum;
   trianglesNum->SetNumberOfComponents(1);
-  trianglesNum->SetNumberOfTuples(nbSplats);
   trianglesNum->SetName("number of triangles");
 
   // number of frames: 1 int (4 bytes)
   vtkNew<vtkIntArray> framesNum;
   framesNum->SetNumberOfComponents(1);
-  framesNum->SetNumberOfTuples(nbSplats);
   framesNum->SetName("number of frames");
 
   //====================================
@@ -122,13 +102,11 @@ int vtkQuakeMDLReader::RequestData(
   // sync type (0: synchron, 1: random): 1 int (4 bytes)
   vtkNew<vtkIntArray> syncType;
   syncType->SetNumberOfComponents(1);
-  syncType->SetNumberOfTuples(nbSplats);
   syncType->SetName("sync type");
 
   // state flags: 1 int (4 bytes)
   vtkNew<vtkIntArray> stateFlags;
   stateFlags->SetNumberOfComponents(1);
-  stateFlags->SetNumberOfTuples(nbSplats);
   stateFlags->SetName("state flags");
 
   //====================================
@@ -136,25 +114,21 @@ int vtkQuakeMDLReader::RequestData(
   // position: 3 floats (12 bytes)
   vtkNew<vtkFloatArray> position;
   position->SetNumberOfComponents(3);
-  position->SetNumberOfTuples(nbSplats);
   position->SetName("position");
 
   // scale: 3 floats (12 bytes)
   vtkNew<vtkFloatArray> scale;
   scale->SetNumberOfComponents(3);
-  scale->SetNumberOfTuples(nbSplats);
   scale->SetName("scale");
 
   // rotation: 4 chars (4 bytes)
   vtkNew<vtkUnsignedCharArray> rotation;
   rotation->SetNumberOfComponents(4);
-  rotation->SetNumberOfTuples(nbSplats);
   rotation->SetName("rotation");
 
   // color+opacity: 4 chars (4 bytes)
   vtkNew<vtkUnsignedCharArray> colorAndOpacity;
   colorAndOpacity->SetNumberOfComponents(4);
-  colorAndOpacity->SetNumberOfTuples(nbSplats);
   colorAndOpacity->SetName("color and opacity");
 
   return 1;