Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
VTK
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Scott Wittenburg
VTK
Commits
e9c97bbf
Commit
e9c97bbf
authored
Mar 09, 2018
by
Michael Migliore
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add OBJ writer
parent
e42e7c4b
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
541 additions
and
0 deletions
+541
-0
IO/Geometry/CMakeLists.txt
IO/Geometry/CMakeLists.txt
+1
-0
IO/Geometry/Testing/Cxx/CMakeLists.txt
IO/Geometry/Testing/Cxx/CMakeLists.txt
+1
-0
IO/Geometry/Testing/Cxx/TestOBJPolyDataWriter.cxx
IO/Geometry/Testing/Cxx/TestOBJPolyDataWriter.cxx
+164
-0
IO/Geometry/Testing/Data/Baseline/TestOBJPolyDataWriter.png.md5
...metry/Testing/Data/Baseline/TestOBJPolyDataWriter.png.md5
+1
-0
IO/Geometry/module.cmake
IO/Geometry/module.cmake
+1
-0
IO/Geometry/vtkOBJWriter.cxx
IO/Geometry/vtkOBJWriter.cxx
+298
-0
IO/Geometry/vtkOBJWriter.h
IO/Geometry/vtkOBJWriter.h
+75
-0
No files found.
IO/Geometry/CMakeLists.txt
View file @
e9c97bbf
...
...
@@ -15,6 +15,7 @@ SET(Module_SRCS
vtkMFIXReader.cxx
vtkMoleculeReaderBase.cxx
vtkOBJReader.cxx
vtkOBJWriter.cxx
vtkOpenFOAMReader.cxx
vtkParticleReader.cxx
vtkPDBReader.cxx
...
...
IO/Geometry/Testing/Cxx/CMakeLists.txt
View file @
e9c97bbf
...
...
@@ -27,6 +27,7 @@ vtk_add_test_cxx(vtkIOGeometryCxxTests tests
UnstructuredGridCellGradients.cxx
UnstructuredGridFastGradients.cxx
UnstructuredGridGradients.cxx
TestOBJPolyDataWriter.cxx
TestOBJReaderComments.cxx,NO_VALID
TestOBJReaderMaterials.cxx,NO_VALID
TestOBJReaderMultiTexture.cxx,NO_VALID
...
...
IO/Geometry/Testing/Cxx/TestOBJPolyDataWriter.cxx
0 → 100644
View file @
e9c97bbf
/*=========================================================================
Program: Visualization Toolkit
Module: TestOBJPolyDataWriter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include <vtkActor.h>
#include <vtkJPEGReader.h>
#include <vtkMath.h>
#include <vtkNew.h>
#include <vtkOBJReader.h>
#include <vtkOBJWriter.h>
#include <vtkPNGReader.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRegressionTestImage.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTestUtilities.h>
#include <vtkTexture.h>
#include <vtkTexturedSphereSource.h>
#include <string>
int
TestOBJPolyDataWriter
(
int
argc
,
char
*
argv
[])
{
vtkNew
<
vtkTexturedSphereSource
>
sphereSource
;
sphereSource
->
SetThetaResolution
(
16
);
sphereSource
->
SetPhiResolution
(
16
);
vtkNew
<
vtkJPEGReader
>
textReader
;
textReader
->
SetFileName
(
vtkTestUtilities
::
ExpandDataFileName
(
argc
,
argv
,
"Data/NE2_ps_bath_small.jpg"
));
std
::
string
tmpDir
(
vtkTestUtilities
::
GetArgOrEnvOrDefault
(
"-T"
,
argc
,
argv
,
"VTK_TEMP_DIR"
,
"Testing/Temporary"
));
std
::
string
filename
=
tmpDir
+
"/TestOBJPolyDataWriter_write.obj"
;
vtkNew
<
vtkOBJWriter
>
writer
;
writer
->
SetFileName
(
filename
.
c_str
());
writer
->
SetInputConnection
(
0
,
sphereSource
->
GetOutputPort
());
writer
->
SetInputConnection
(
1
,
textReader
->
GetOutputPort
());
writer
->
Write
();
vtkPolyData
*
polyInput
=
sphereSource
->
GetOutput
();
// read this file and compare with input
vtkNew
<
vtkOBJReader
>
reader
;
reader
->
SetFileName
(
filename
.
c_str
());
reader
->
Update
();
vtkPolyData
*
polyOutput
=
reader
->
GetOutput
();
if
(
polyInput
->
GetNumberOfPoints
()
!=
polyOutput
->
GetNumberOfPoints
())
{
cerr
<<
"PolyData do not have the same number of points.
\n
"
;
return
EXIT_FAILURE
;
}
vtkDataArray
*
positionsInput
=
polyInput
->
GetPoints
()
->
GetData
();
vtkDataArray
*
positionsOutput
=
polyOutput
->
GetPoints
()
->
GetData
();
vtkDataArray
*
normalsInput
=
polyInput
->
GetPointData
()
->
GetNormals
();
vtkDataArray
*
normalsOutput
=
polyOutput
->
GetPointData
()
->
GetNormals
();
vtkDataArray
*
tcoordsInput
=
polyInput
->
GetPointData
()
->
GetTCoords
();
vtkDataArray
*
tcoordsOutput
=
polyOutput
->
GetPointData
()
->
GetTCoords
();
if
(
!
positionsInput
||
!
positionsOutput
||
!
normalsInput
||
!
normalsOutput
||
!
tcoordsInput
||
!
tcoordsOutput
)
{
cerr
<<
"One of the arrays is null.
\n
"
;
return
EXIT_FAILURE
;
}
// check values
for
(
vtkIdType
i
=
0
;
i
<
polyInput
->
GetNumberOfPoints
();
i
++
)
{
double
pi
[
3
],
po
[
3
];
// check positions
positionsInput
->
GetTuple
(
i
,
pi
);
positionsOutput
->
GetTuple
(
i
,
po
);
if
(
vtkMath
::
Distance2BetweenPoints
(
pi
,
po
)
>
1e-4
)
{
cerr
<<
"One point is different.
\n
"
;
cerr
<<
"Input: "
<<
pi
[
0
]
<<
" "
<<
pi
[
1
]
<<
" "
<<
pi
[
2
]
<<
"
\n
"
;
cerr
<<
"Output: "
<<
po
[
0
]
<<
" "
<<
po
[
1
]
<<
" "
<<
po
[
2
]
<<
"
\n
"
;
return
EXIT_FAILURE
;
}
// check normals
normalsInput
->
GetTuple
(
i
,
pi
);
normalsOutput
->
GetTuple
(
i
,
po
);
if
(
vtkMath
::
AngleBetweenVectors
(
pi
,
po
)
>
1e-6
)
{
cerr
<<
"One normal is different:
\n
"
;
cerr
<<
"Input: "
<<
pi
[
0
]
<<
" "
<<
pi
[
1
]
<<
" "
<<
pi
[
2
]
<<
"
\n
"
;
cerr
<<
"Output: "
<<
po
[
0
]
<<
" "
<<
po
[
1
]
<<
" "
<<
po
[
2
]
<<
"
\n
"
;
return
EXIT_FAILURE
;
}
// check texture coords
tcoordsInput
->
GetTuple
(
i
,
pi
);
tcoordsOutput
->
GetTuple
(
i
,
po
);
pi
[
2
]
=
po
[
2
]
=
0.0
;
if
(
vtkMath
::
Distance2BetweenPoints
(
pi
,
po
)
>
1e-4
)
{
cerr
<<
"One texture coord is different:
\n
"
;
cerr
<<
"Input: "
<<
pi
[
0
]
<<
" "
<<
pi
[
1
]
<<
"
\n
"
;
cerr
<<
"Output: "
<<
po
[
0
]
<<
" "
<<
po
[
1
]
<<
"
\n
"
;
return
EXIT_FAILURE
;
}
}
vtkNew
<
vtkPolyDataMapper
>
mapper
;
mapper
->
SetInputConnection
(
reader
->
GetOutputPort
());
// read png file and set up texture
vtkNew
<
vtkPNGReader
>
pngReader
;
std
::
string
pngFile
=
filename
.
replace
(
filename
.
length
()
-
3
,
3
,
"png"
);
pngReader
->
SetFileName
(
pngFile
.
c_str
());
vtkNew
<
vtkTexture
>
texture
;
texture
->
SetInputConnection
(
pngReader
->
GetOutputPort
());
// add mapper and texture in an actor
vtkNew
<
vtkActor
>
actor
;
actor
->
SetMapper
(
mapper
);
actor
->
SetTexture
(
texture
);
// Standard rendering classes
vtkNew
<
vtkRenderer
>
renderer
;
vtkNew
<
vtkRenderWindow
>
renWin
;
renWin
->
AddRenderer
(
renderer
);
vtkNew
<
vtkRenderWindowInteractor
>
iren
;
iren
->
SetRenderWindow
(
renWin
);
// set up the view
renderer
->
SetBackground
(
0.5
,
0.5
,
0.5
);
renWin
->
SetSize
(
300
,
300
);
renderer
->
AddActor
(
actor
);
renderer
->
ResetCamera
();
renWin
->
Render
();
int
retVal
=
vtkRegressionTestImage
(
renWin
);
if
(
retVal
==
vtkRegressionTester
::
DO_INTERACTOR
)
{
iren
->
Start
();
}
return
!
retVal
;
}
IO/Geometry/Testing/Data/Baseline/TestOBJPolyDataWriter.png.md5
0 → 100644
View file @
e9c97bbf
f55901f24762b2efbe234d8a5d1ec6b9
IO/Geometry/module.cmake
View file @
e9c97bbf
...
...
@@ -20,6 +20,7 @@ vtk_module(vtkIOGeometry
vtkCommonMisc
vtkCommonSystem
vtkCommonTransforms
vtkIOImage
vtksys
vtkzlib
)
IO/Geometry/vtkOBJWriter.cxx
0 → 100644
View file @
e9c97bbf
/*=========================================================================
Program: Visualization Toolkit
Module: vtkOBJWriter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkOBJWriter.h"
#include "vtkDataSet.h"
#include "vtkErrorCode.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkPNGWriter.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkTriangleStrip.h"
#include "vtksys/SystemTools.hxx"
namespace
{
//----------------------------------------------------------------------------
void
WriteFaces
(
std
::
ofstream
&
f
,
vtkCellArray
*
faces
,
bool
withNormals
,
bool
withTCoords
)
{
vtkIdType
npts
;
vtkIdType
*
indx
;
for
(
faces
->
InitTraversal
();
faces
->
GetNextCell
(
npts
,
indx
);)
{
f
<<
"f"
;
for
(
vtkIdType
i
=
0
;
i
<
npts
;
i
++
)
{
f
<<
" "
<<
indx
[
i
]
+
1
;
if
(
withTCoords
)
{
f
<<
"/"
<<
indx
[
i
]
+
1
;
if
(
withNormals
)
{
f
<<
"/"
<<
indx
[
i
]
+
1
;
}
}
else
if
(
withNormals
)
{
f
<<
"//"
<<
indx
[
i
]
+
1
;
}
}
f
<<
"
\n
"
;
}
}
//----------------------------------------------------------------------------
void
WriteLines
(
std
::
ofstream
&
f
,
vtkCellArray
*
lines
)
{
vtkIdType
npts
;
vtkIdType
*
indx
;
for
(
lines
->
InitTraversal
();
lines
->
GetNextCell
(
npts
,
indx
);)
{
f
<<
"l"
;
for
(
vtkIdType
i
=
0
;
i
<
npts
;
i
++
)
{
f
<<
" "
<<
indx
[
i
]
+
1
;
}
f
<<
"
\n
"
;
}
}
//----------------------------------------------------------------------------
void
WritePoints
(
std
::
ofstream
&
f
,
vtkPoints
*
pts
,
vtkDataArray
*
normals
,
vtkDataArray
*
tcoords
)
{
vtkIdType
nbPts
=
pts
->
GetNumberOfPoints
();
// Positions
for
(
vtkIdType
i
=
0
;
i
<
nbPts
;
i
++
)
{
double
p
[
3
];
pts
->
GetPoint
(
i
,
p
);
f
<<
"v "
<<
p
[
0
]
<<
" "
<<
p
[
1
]
<<
" "
<<
p
[
2
]
<<
"
\n
"
;
}
// Normals
if
(
normals
)
{
for
(
vtkIdType
i
=
0
;
i
<
nbPts
;
i
++
)
{
double
p
[
3
];
normals
->
GetTuple
(
i
,
p
);
f
<<
"vn "
<<
p
[
0
]
<<
" "
<<
p
[
1
]
<<
" "
<<
p
[
2
]
<<
"
\n
"
;
}
}
// Textures
if
(
tcoords
)
{
for
(
vtkIdType
i
=
0
;
i
<
nbPts
;
i
++
)
{
double
p
[
2
];
tcoords
->
GetTuple
(
i
,
p
);
f
<<
"vt "
<<
p
[
0
]
<<
" "
<<
p
[
1
]
<<
"
\n
"
;
}
}
}
//----------------------------------------------------------------------------
bool
WriteTexture
(
std
::
ofstream
&
f
,
const
std
::
string
&
baseName
,
vtkImageData
*
texture
)
{
std
::
string
mtlName
=
baseName
+
".mtl"
;
std
::
ofstream
fmtl
(
mtlName
,
std
::
ofstream
::
out
);
if
(
fmtl
.
fail
())
{
return
false
;
}
// write png file
std
::
string
pngName
=
baseName
+
".png"
;
vtkNew
<
vtkPNGWriter
>
pngWriter
;
pngWriter
->
SetInputData
(
texture
);
pngWriter
->
SetFileName
(
pngName
.
c_str
());
pngWriter
->
Write
();
// remove directories
mtlName
=
vtksys
::
SystemTools
::
GetFilenameName
(
mtlName
);
pngName
=
vtksys
::
SystemTools
::
GetFilenameName
(
pngName
);
// set material
fmtl
<<
"newmtl vtktexture
\n
"
;
fmtl
<<
"map_Kd "
<<
pngName
<<
"
\n
"
;
// declare material in obj file
f
<<
"mtllib "
+
mtlName
+
"
\n
"
;
f
<<
"usemtl vtktexture
\n
"
;
return
true
;
}
}
//----------------------------------------------------------------------------
vtkStandardNewMacro
(
vtkOBJWriter
);
//----------------------------------------------------------------------------
vtkOBJWriter
::
vtkOBJWriter
()
{
this
->
FileName
=
nullptr
;
this
->
SetNumberOfInputPorts
(
2
);
}
//----------------------------------------------------------------------------
vtkOBJWriter
::~
vtkOBJWriter
()
{
this
->
SetFileName
(
nullptr
);
}
//----------------------------------------------------------------------------
void
vtkOBJWriter
::
WriteData
()
{
vtkPolyData
*
input
=
this
->
GetInputGeometry
();
vtkImageData
*
texture
=
this
->
GetInputTexture
();
if
(
input
==
nullptr
)
{
vtkErrorMacro
(
"No geometry to write!"
);
this
->
SetErrorCode
(
vtkErrorCode
::
UnknownError
);
return
;
}
vtkPoints
*
pts
=
input
->
GetPoints
();
vtkCellArray
*
polys
=
input
->
GetPolys
();
vtkCellArray
*
strips
=
input
->
GetStrips
();
vtkCellArray
*
lines
=
input
->
GetLines
();
vtkDataArray
*
normals
=
input
->
GetPointData
()
->
GetNormals
();
vtkDataArray
*
tcoords
=
input
->
GetPointData
()
->
GetTCoords
();
if
(
pts
==
nullptr
)
{
vtkErrorMacro
(
"No data to write!"
);
this
->
SetErrorCode
(
vtkErrorCode
::
UnknownError
);
return
;
}
if
(
this
->
FileName
==
nullptr
)
{
vtkErrorMacro
(
"Please specify FileName to write"
);
this
->
SetErrorCode
(
vtkErrorCode
::
NoFileNameError
);
return
;
}
vtkIdType
npts
=
0
;
std
::
ofstream
f
(
this
->
FileName
,
std
::
ofstream
::
out
);
if
(
f
.
fail
())
{
vtkErrorMacro
(
"Unable to open file: "
<<
this
->
FileName
);
this
->
SetErrorCode
(
vtkErrorCode
::
CannotOpenFileError
);
return
;
}
// Write header
f
<<
"# Generated by Visualization Toolkit
\n
"
;
// Write material if a texture is specified
if
(
texture
)
{
std
::
vector
<
std
::
string
>
comp
;
vtksys
::
SystemTools
::
SplitPath
(
vtksys
::
SystemTools
::
GetFilenamePath
(
this
->
FileName
),
comp
);
comp
.
push_back
(
vtksys
::
SystemTools
::
GetFilenameWithoutLastExtension
(
this
->
FileName
));
if
(
!::
WriteTexture
(
f
,
vtksys
::
SystemTools
::
JoinPath
(
comp
),
texture
))
{
vtkErrorMacro
(
"Unable to create material file"
);
}
}
// Write points
::
WritePoints
(
f
,
pts
,
normals
,
tcoords
);
// Decompose any triangle strips into triangles
vtkNew
<
vtkCellArray
>
polyStrips
;
if
(
strips
->
GetNumberOfCells
()
>
0
)
{
vtkIdType
*
ptIds
=
nullptr
;
for
(
strips
->
InitTraversal
();
strips
->
GetNextCell
(
npts
,
ptIds
);)
{
vtkTriangleStrip
::
DecomposeStrip
(
npts
,
ptIds
,
polyStrips
);
}
}
// Write triangle strips
::
WriteFaces
(
f
,
polyStrips
,
normals
!=
nullptr
,
tcoords
!=
nullptr
);
// Write polygons.
if
(
polys
)
{
::
WriteFaces
(
f
,
polys
,
normals
!=
nullptr
,
tcoords
!=
nullptr
);
}
// Write lines.
if
(
lines
)
{
::
WriteLines
(
f
,
lines
);
}
f
.
close
();
}
//----------------------------------------------------------------------------
void
vtkOBJWriter
::
PrintSelf
(
ostream
&
os
,
vtkIndent
indent
)
{
this
->
Superclass
::
PrintSelf
(
os
,
indent
);
os
<<
indent
<<
"FileName: "
<<
(
this
->
GetFileName
()
?
this
->
GetFileName
()
:
"(none)"
)
<<
endl
;
os
<<
indent
<<
"Input: "
<<
this
->
GetInputGeometry
()
<<
endl
;
vtkImageData
*
texture
=
this
->
GetInputTexture
();
if
(
texture
)
{
os
<<
indent
<<
"Texture:"
<<
endl
;
texture
->
PrintSelf
(
os
,
indent
.
GetNextIndent
());
}
}
//----------------------------------------------------------------------------
vtkPolyData
*
vtkOBJWriter
::
GetInputGeometry
()
{
return
vtkPolyData
::
SafeDownCast
(
this
->
GetInput
(
0
));
}
//----------------------------------------------------------------------------
vtkImageData
*
vtkOBJWriter
::
GetInputTexture
()
{
return
vtkImageData
::
SafeDownCast
(
this
->
GetInput
(
1
));
}
//----------------------------------------------------------------------------
vtkDataSet
*
vtkOBJWriter
::
GetInput
(
int
port
)
{
return
vtkDataSet
::
SafeDownCast
(
this
->
Superclass
::
GetInput
(
port
));
}
//----------------------------------------------------------------------------
int
vtkOBJWriter
::
FillInputPortInformation
(
int
port
,
vtkInformation
*
info
)
{
if
(
port
==
0
)
{
info
->
Set
(
vtkDataObject
::
DATA_TYPE_NAME
(),
"vtkPolyData"
);
return
1
;
}
if
(
port
==
1
)
{
info
->
Set
(
vtkDataObject
::
DATA_TYPE_NAME
(),
"vtkImageData"
);
info
->
Set
(
vtkAlgorithm
::
INPUT_IS_OPTIONAL
(),
1
);
return
1
;
}
return
0
;
}
IO/Geometry/vtkOBJWriter.h
0 → 100644
View file @
e9c97bbf
/*=========================================================================
Program: Visualization Toolkit
Module: vtkOBJWriter.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkOBJWriter
* @brief write wavefront obj file
*
* vtkOBJWriter writes wavefront obj (.obj) files in ASCII form.
* OBJ files contain the geometry including lines, triangles and polygons.
* Normals and texture coordinates on points are also written if they exist.
* One can specify a texture passing a vtkImageData on port 1.
* If a texture is set, additionals .mtl and .png files are generated. Those files have the same
* name without obj extension.
*/
#ifndef vtkOBJWriter_h
#define vtkOBJWriter_h
#include "vtkIOGeometryModule.h" // For export macro
#include "vtkWriter.h"
class
vtkDataSet
;
class
vtkImageData
;
class
vtkPolyData
;
class
VTKIOGEOMETRY_EXPORT
vtkOBJWriter
:
public
vtkWriter
{
public:
static
vtkOBJWriter
*
New
();
vtkTypeMacro
(
vtkOBJWriter
,
vtkWriter
);
void
PrintSelf
(
ostream
&
os
,
vtkIndent
indent
)
override
;
//@{
/**
* Get the inputs to this writer.
*/
vtkPolyData
*
GetInputGeometry
();
vtkImageData
*
GetInputTexture
();
vtkDataSet
*
GetInput
(
int
port
);
//@}
//@{
/**
* Get/Set the file name of the OBJ file.
*/
vtkSetStringMacro
(
FileName
);
vtkGetStringMacro
(
FileName
);
//@}
protected:
vtkOBJWriter
();
~
vtkOBJWriter
()
override
;
void
WriteData
()
override
;
int
FillInputPortInformation
(
int
port
,
vtkInformation
*
info
)
override
;
char
*
FileName
;
private:
vtkOBJWriter
(
const
vtkOBJWriter
&
)
=
delete
;
void
operator
=
(
const
vtkOBJWriter
&
)
=
delete
;
};
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment