Compare commits

..

No commits in common. "master" and "architecture-rework" have entirely different histories.

183 changed files with 23753 additions and 704953 deletions

View File

@ -1,51 +0,0 @@
cmake_minimum_required(VERSION 3.15)
project(tp LANGUAGES C CXX)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
add_subdirectory(external/OpenMesh)
add_subdirectory(external/Eigen)
add_subdirectory(external/MeshReconstruction)
target_include_directories(MeshReconstruction INTERFACE
external/MeshReconstruction/lib)
add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME} PRIVATE
resources.qrc
src/main.cpp
src/main_window.cpp
src/main_window.h
src/mesh_processor.cpp
src/mesh_processor.h
src/mesh_view.cpp
src/mesh_view.h
src/mesh_viewer.cpp
src/mesh_viewer.h
src/my_mesh.h
src/smoothing.cpp
src/smoothing.h
src/util.cpp
src/util.h
src/curvature.cpp
src/curvature.h
src/quad_patch.cpp
src/quad_patch.h
src/quad_patch_tesselator.cpp
src/quad_patch_tesselator.h
src/hole_filling.cpp
src/hole_filling.h
src/double_input.cpp
src/double_input.h
src/noise_removal.cpp
src/noise_removal.h)
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt5::Core Qt5::Gui Qt5::Widgets
OpenMeshCore
eigen
MeshReconstruction)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
set_target_properties(${PROJECT_NAME} PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON)

View File

@ -1,29 +0,0 @@
TP de modélisation géométrique réalisé dans le cadre du M2 GIG
par Jérémy André et Cyril Colin
Ceci comprend les fonctionalités suivantes :
- remplissage de trous (dans src/hole_filling.cpp)
- analyse de courbure (dans src/curvature.cpp)
- adoucissement d'un maillage par laplacien uniforme ou cotangent (dans
src/smoothing.cpp)
- suppression de parasites (dans src/noise_removal.cpp)
Des maillages exemples sont inclus, data/gargoyle_trou.obj est un
bon exemple pour le remplissage, data/bunnyLowPoly-noisy.obj pour
l'adoucissement et data/bunny.obj pour la suppression de parasites.
Compilation
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release
puis
cmake --build build
Exécution
build/tp [FICHIER OBJ]
Dépendances
- Eigen (téléchargée automatiquement)
- Openmesh (téléchargée automatiquement)
- MeshReconstruction (inclue dans `external')

View File

@ -1,8 +0,0 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
o Plane_Plane.002
v -0.794484 1.011246 0.588367
v 0.794484 -0.055750 1.168626
v 0.794484 -1.011246 -0.588367
s off
f 2 3 1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,30 @@
# Blender v2.90.1 OBJ File: ''
# www.blender.org
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
usemtl Material
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
s off
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6
f 2//1 3//1 1//1
f 4//2 7//2 3//2
f 8//3 5//3 7//3
f 6//4 1//4 5//4
f 7//5 1//5 3//5
f 4//6 6//6 8//6
f 2//1 4//1 3//1
f 4//2 8//2 7//2
f 8//3 6//3 5//3
f 6//4 2//4 1//4
f 7//5 5//5 1//5
f 4//6 2//6 6//6

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,11 +0,0 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
mtllib tri.mtl
o Plane
v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v 1.000000 0.000000 -1.000000
vn 0.0000 1.0000 0.0000
usemtl None
s off
f 2//1 3//1 1//1

View File

@ -1,10 +0,0 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,14 +0,0 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
mtllib tri2.mtl
o Plane
v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v 1.000000 0.000000 -1.000000
v 0.367291 0.000000 0.367291
vn 0.0000 1.0000 0.0000
usemtl None
s off
f 4//1 1//1 2//1
f 4//1 2//1 3//1
f 4//1 3//1 1//1

View File

@ -1,10 +0,0 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,16 +0,0 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
mtllib tri3.mtl
o Plane
v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v 1.000000 0.000000 -1.000000
v 0.367291 0.755325 0.367291
vn 0.0000 0.6421 0.7666
vn 0.7666 0.6421 0.0000
vn -0.5826 0.5666 -0.5826
usemtl None
s off
f 4//1 1//1 2//1
f 4//2 2//2 3//2
f 4//3 3//3 1//3

View File

@ -1,11 +0,0 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
o Plane
v -1.000000 -0.789036 -0.614347
v 1.000000 -0.789036 -0.614347
v 1.000000 0.789036 0.614347
v 0.367291 -0.753837 0.370334
s off
f 4 1 2
f 4 2 3
f 4 3 1

View File

@ -1,10 +0,0 @@
cmake_minimum_required(VERSION 3.15)
include(FetchContent)
FetchContent_Declare(
Eigen
URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
URL_HASH MD5=4c527a9171d71a72a9d4186e65bea559)
FetchContent_MakeAvailable(Eigen)

View File

@ -1,3 +0,0 @@
bin
html/
latex/

View File

@ -1,16 +0,0 @@
cmake_minimum_required (VERSION 3.0)
project (MeshReconstruction)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Parallel compilation.
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250")
endif()
set(CMAKE_DEBUG_POSTFIX "d")
add_subdirectory(lib)
add_subdirectory(demo)

View File

@ -1,13 +0,0 @@
# MeshReconstruction
This is a small library that can reconstruct a triangle mesh from a <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">signed distance function</a> using the <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes algorithm</a> and export it to a file in the <a href="https://de.wikipedia.org/wiki/Wavefront_OBJ">obj format</a>.
The library is self-contained and has no dependencies. The library is fast due to precomputed lookup tables and a narrow-band approach which excludes a lot of marching cubes that are far away from the surface.
The library requires C++14 and has been tested under Visual Studio 2017 and Windows 10 but should port to other systems without major problems.
The library can be used under the terms of the MIT License.
<p align="center">
<img src="overview.png" width="400" alt="Overview">
</p>

View File

@ -1,3 +0,0 @@
include_directories("." ${PROJECT_SOURCE_DIR}/lib)
add_executable(Demo main.cpp)
target_link_libraries (Demo MeshReconstruction)

View File

@ -1,22 +0,0 @@
#include <MeshReconstruction.h>
#include <IO.h>
using namespace MeshReconstruction;
int main()
{
auto sphereSdf = [](Vec3 const& pos)
{
auto const Radius = 1.0;
return pos.Norm() - Radius;
};
Rect3 domain;
domain.min = { -1.1, -1.1, -1.1 };
domain.size = {2.2, 2.2, 2.2};
Vec3 cubeSize{ 0.05, 0.05, 0.05 };
auto mesh = MarchCube(sphereSdf, domain, cubeSize);
WriteObjFile(mesh, "sphere.obj");
}

View File

@ -1,10 +0,0 @@
add_library(MeshReconstruction MeshReconstruction.h MeshReconstruction.cpp Cube.h Cube.cpp DataStructs.h IO.h IO.cpp Triangulation.h Triangulation.cpp)
install(TARGETS MeshReconstruction
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
install(DIRECTORY .
DESTINATION .
FILES_MATCHING PATTERN "*.h")

View File

@ -1,148 +0,0 @@
#include "Cube.h"
using namespace MeshReconstruction;
namespace
{
// Cube has 8 vertices. Each vertex can have positive or negative sign.
// 2^8 = 256 possible configurations mapped to intersected edges in each case.
// The 12 edges are numbered as 1, 2, 4, ..., 2048 and are stored as a 12-bit bitstring for each configuration.
const int signConfigToIntersectedEdges[256] = {
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 };
struct Edge
{
unsigned edgeFlag : 12; // flag: 1, 2, 4, ... 2048
int vert0; // 0-7
int vert1; // 0-7
};
const Edge edges[12] =
{
{ 1, 0, 1 }, // edge 0
{ 2, 1, 2 }, // edge 1
{ 4, 2, 3 }, // ...
{ 8, 3, 0 },
{ 16, 4, 5 },
{ 32, 5, 6 },
{ 64, 6, 7 },
{ 128, 7, 4 },
{ 256, 0, 4 },
{ 512, 1, 5 },
{ 1024, 2, 6 },
{ 2048, 3, 7 } // edge 11
};
}
Vec3 Cube::LerpVertex(double isoLevel, int i1, int i2) const
{
auto const Eps = 1e-5;
auto const v1 = sdf[i1];
auto const v2 = sdf[i2];
auto const& p1 = pos[i1];
auto const& p2 = pos[i2];
if (std::abs(isoLevel - v1) < Eps) return p1;
if (std::abs(isoLevel - v2) < Eps) return p2;
if (std::abs(v1 - v2) < Eps) return p1;
auto mu = (isoLevel - v1) / (v2 - v1);
return p1 + (p2 - p1)*mu;
}
Cube::Cube(Rect3 const& space, Fun3s const& sdf)
{
auto mx = space.min.x;
auto my = space.min.y;
auto mz = space.min.z;
auto sx = space.size.x;
auto sy = space.size.y;
auto sz = space.size.z;
pos[0] = space.min;
pos[1] = { mx + sx, my, mz };
pos[2] = { mx + sx, my, mz + sz };
pos[3] = { mx, my, mz + sz };
pos[4] = { mx, my + sy, mz };
pos[5] = { mx + sx, my + sy, mz };
pos[6] = { mx + sx, my + sy, mz + sz };
pos[7] = { mx, my + sy, mz + sz };
for (auto i = 0; i < 8; ++i)
{
auto sd = sdf(pos[i]);
if (sd == 0) sd += 1e-6;
this->sdf[i] = sd;
}
}
int Cube::SignConfig(double isoLevel) const
{
auto edgeIndex = 0;
for (auto i = 0; i < 8; ++i)
{
if (sdf[i] < isoLevel)
{
edgeIndex |= (1 << i);
}
}
return edgeIndex;
}
IntersectInfo Cube::Intersect(double iso) const
{
// idea:
// from signs at 8 corners of cube a sign configuration (256 possible ones) is computed
// this configuration can be used to index into a table that tells which of the 12 edges are intersected
// find vertices adjacent to edges and interpolate cut vertex and store it in IntersectionInfo object
IntersectInfo intersect;
intersect.signConfig = SignConfig(iso);
auto intersectedEdges = signConfigToIntersectedEdges[intersect.signConfig];
for (auto e = 0; e<12; ++e)
{
if (intersectedEdges & edges[e].edgeFlag)
{
auto v0 = edges[e].vert0;
auto v1 = edges[e].vert1;
auto vert = LerpVertex(iso, v0, v1);
intersect.edgeVertIndices[e] = vert;
}
}
return intersect;
}

View File

@ -1,30 +0,0 @@
#pragma once
#include "DataStructs.h"
namespace MeshReconstruction
{
struct IntersectInfo
{
// 0 - 255
int signConfig;
// If it exists, vertex on edge i is stored at position i.
// For edge numbering and location see numberings.png.
std::array<Vec3, 12> edgeVertIndices;
};
class Cube
{
Vec3 pos[8];
double sdf[8];
Vec3 LerpVertex(double isoLevel, int i1, int i2) const;
int SignConfig(double isoLevel) const;
public:
Cube(Rect3 const& space, Fun3s const& sdf);
// Find the vertices where the surface intersects the cube.
IntersectInfo Intersect(double isoLevel = 0) const;
};
}

View File

@ -1,57 +0,0 @@
#pragma once
#include <vector>
#include <array>
#include <functional>
#include <cmath>
namespace MeshReconstruction
{
struct Vec3
{
double x, y, z;
Vec3 operator+(Vec3 const& o) const
{
return { x + o.x, y + o.y, z + o.z };
}
Vec3 operator-(Vec3 const& o) const
{
return { x - o.x, y - o.y, z - o.z };
}
Vec3 operator*(double c) const
{
return { c*x, c*y, c*z };
}
double Norm() const
{
return sqrt(x*x + y*y + z*z);
}
Vec3 Normalized() const
{
auto n = Norm();
return { x / n, y / n, z / n };
}
};
struct Rect3
{
Vec3 min;
Vec3 size;
};
using Triangle = std::array<int, 3>;
struct Mesh
{
std::vector<Vec3> vertices;
std::vector<Triangle> triangles;
std::vector<Vec3> vertexNormals;
};
using Fun3s = std::function<double(Vec3 const&)>;
using Fun3v = std::function<Vec3(Vec3 const&)>;
}

View File

@ -1,47 +0,0 @@
#include "IO.h"
#include <stdexcept>
using namespace std;
void MeshReconstruction::WriteObjFile(Mesh const& mesh, string const& fileName)
{
// FILE faster than streams.
FILE* file = fopen(fileName.c_str(), "w");
if (file == NULL)
{
throw runtime_error("Could not write obj file.");
}
// write stats
fprintf(file, "# %d vertices, %d triangles\n\n",
static_cast<int>(mesh.vertices.size()),
static_cast<int>(mesh.triangles.size()));
// vertices
for (size_t vi = 0; vi < mesh.vertices.size(); ++vi)
{
auto const& v = mesh.vertices.at(vi);
fprintf(file, "v %f %f %f\n", v.x, v.y, v.z);
}
// vertex normals
fprintf(file, "\n");
for (size_t ni = 0; ni < mesh.vertices.size(); ++ni)
{
auto const& vn = mesh.vertexNormals.at(ni);
fprintf(file, "vn %f %f %f\n", vn.x, vn.y, vn.z);
}
// triangles (1-based)
fprintf(file, "\n");
for (size_t ti = 0; ti < mesh.triangles.size(); ++ti)
{
auto const& t = mesh.triangles.at(ti);
fprintf(file, "f %d//%d %d//%d %d//%d\n",
t[0] + 1, t[0] + 1,
t[1] + 1, t[1] + 1,
t[2] + 1, t[2] + 1);
}
fclose(file);
}

View File

@ -1,9 +0,0 @@
#pragma once
#include <string>
#include "DataStructs.h"
namespace MeshReconstruction
{
/// Writes a mesh to a file in <a href="https://de.wikipedia.org/wiki/Wavefront_OBJ">obj format</a>.
void WriteObjFile(Mesh const& mesh, std::string const& file);
}

View File

@ -1,79 +0,0 @@
#include "MeshReconstruction.h"
#include "Cube.h"
#include "Triangulation.h"
#include <iostream>
using namespace MeshReconstruction;
using namespace std;
// Adapted from here: http://paulbourke.net/geometry/polygonise/
namespace
{
Vec3 NumGrad(Fun3s const& f, Vec3 const& p)
{
auto const Eps = 1e-6;
Vec3 epsX{ Eps, 0, 0 }, epsY{ 0, Eps, 0 }, epsZ{ 0, 0, Eps };
auto gx = (f(p + epsX) - f(p - epsX)) / 2;
auto gy = (f(p + epsY) - f(p - epsY)) / 2;
auto gz = (f(p + epsZ) - f(p - epsZ)) / 2;
return { gx, gy, gz };
}
}
Mesh MeshReconstruction::MarchCube(Fun3s const& sdf, Rect3 const& domain)
{
auto const NumCubes = 50;
auto cubeSize = domain.size * (1.0 / NumCubes);
return MarchCube(sdf, domain, cubeSize);
}
Mesh MeshReconstruction::MarchCube(
Fun3s const& sdf,
Rect3 const& domain,
Vec3 const& cubeSize,
double isoLevel,
Fun3v sdfGrad)
{
// Default value.
sdfGrad = sdfGrad == nullptr
? [&sdf](Vec3 const& p) { return NumGrad(sdf, p); }
: sdfGrad;
auto const NumX = static_cast<int>(ceil(domain.size.x / cubeSize.x));
auto const NumY = static_cast<int>(ceil(domain.size.y / cubeSize.y));
auto const NumZ = static_cast<int>(ceil(domain.size.z / cubeSize.z));
auto const CubeDiag = cubeSize.Norm();
// auto const HalfCubeDiag = cubeSize.Norm() * 0.5;
// auto const HalfCubeSize = cubeSize * 0.5;
Mesh mesh;
for (auto ix = 0; ix < NumX; ++ix)
{
auto x = domain.min.x + ix * cubeSize.x;
for (auto iy = 0; iy < NumY; ++iy)
{
auto y = domain.min.y + iy * cubeSize.y;
for (auto iz = 0; iz < NumZ; ++iz)
{
auto z = domain.min.z + iz * cubeSize.z;
Vec3 min{ x, y, z };
// Process only if cube lies within narrow band around surface.
// auto cubeCenter = min + HalfCubeSize;
// double dist = std::abs(sdf(cubeCenter) - isoLevel);
double dist = std::abs(sdf(min) - isoLevel);
// if (dist > CubeDiag) continue;
Cube cube({ min, cubeSize }, sdf);
auto intersect = cube.Intersect(isoLevel);
Triangulate(intersect, sdfGrad, mesh);
}
}
}
return mesh;
}

View File

@ -1,27 +0,0 @@
#pragma once
#include "DataStructs.h"
namespace MeshReconstruction
{
/// Reconstructs a triangle mesh from a given signed distance function using <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes</a>.
/// @param sdf The <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">Signed Distance Function</a>.
/// @param domain Domain of reconstruction.
/// @returns The reconstructed mesh.
Mesh MarchCube(
Fun3s const& sdf,
Rect3 const& domain);
/// Reconstructs a triangle mesh from a given signed distance function using <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes</a>.
/// @param sdf The <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">Signed Distance Function</a>.
/// @param domain Domain of reconstruction.
/// @param cubeSize Size of marching cubes. Smaller cubes yields meshes of higher resolution.
/// @param isoLevel Level set of the SDF for which triangulation should be done. Changing this value moves the reconstructed surface.
/// @param sdfGrad Gradient of the SDF which yields the vertex normals of the reconstructed mesh. If none is provided a numerical approximation is used.
/// @returns The reconstructed mesh.
Mesh MarchCube(
Fun3s const& sdf,
Rect3 const& domain,
Vec3 const& cubeSize,
double isoLevel = 0,
Fun3v sdfGrad = nullptr);
}

View File

@ -1,301 +0,0 @@
#include "Triangulation.h"
namespace
{
// Indices into vertex buffer (0 - 11).
// Three successive entries make up one triangle.
// -1 means unused.
const int signConfigToTriangles[256][16] =
{ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
{ 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
{ 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
{ 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
{ 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
{ 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
{ 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
{ 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
{ 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
{ 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 },
{ 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
{ 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 },
{ 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 },
{ 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
{ 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 },
{ 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
{ 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
{ 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
{ 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 },
{ 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
{ 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
{ 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 },
{ 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
{ 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 },
{ 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
{ 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
{ 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
{ 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 },
{ 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
{ 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
{ 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
{ 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
{ 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
{ 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
{ 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 },
{ 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
{ 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 },
{ 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
{ 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
{ 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
{ 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
{ 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 },
{ 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
{ 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 },
{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 },
{ 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
{ 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
{ 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
{ 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 },
{ 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
{ 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
{ 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 },
{ 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
{ 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 },
{ 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 },
{ 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 },
{ 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
{ 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 },
{ 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
{ 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
{ 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 },
{ 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
{ 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 },
{ 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
{ 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 },
{ 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
{ 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
{ 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 },
{ 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 },
{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
{ 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 },
{ 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
{ 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 },
{ 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 },
{ 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 },
{ 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
{ 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
{ 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
{ 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 },
{ 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
{ 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
{ 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 },
{ 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
{ 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
{ 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 },
{ 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
{ 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 },
{ 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
{ 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 },
{ 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 },
{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 },
{ 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
{ 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 },
{ 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
{ 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 },
{ 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
{ 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 },
{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
{ 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
{ 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
{ 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 },
{ 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
{ 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 },
{ 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
{ 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
{ 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 },
{ 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } };
}
/// Given a grid cube and an isolevel the triangles (5 max)
/// required to represent the isosurface in the cube are computed.
void MeshReconstruction::Triangulate(
IntersectInfo const& intersect,
Fun3v const& grad,
Mesh& mesh)
{
// Cube is entirely in/out of the surface. Generate no triangles.
if (intersect.signConfig == 0 || intersect.signConfig == 255) return;
auto const& tri = signConfigToTriangles[intersect.signConfig];
for (auto i = 0; tri[i] != -1; i += 3)
{
auto const& v0 = intersect.edgeVertIndices[tri[i]];
auto const& v1 = intersect.edgeVertIndices[tri[i + 1]];
auto const& v2 = intersect.edgeVertIndices[tri[i + 2]];
mesh.vertices.push_back(v0);
mesh.vertices.push_back(v1);
mesh.vertices.push_back(v2);
auto normal0 = grad(v0).Normalized();
auto normal1 = grad(v1).Normalized();
auto normal2 = grad(v2).Normalized();
mesh.vertexNormals.push_back(normal0);
mesh.vertexNormals.push_back(normal1);
mesh.vertexNormals.push_back(normal2);
auto last = static_cast<int>(mesh.vertices.size() - 1);
mesh.triangles.push_back({ last - 2, last - 1, last });
}
}

View File

@ -1,11 +0,0 @@
#pragma once
#include "Cube.h"
#include "DataStructs.h"
namespace MeshReconstruction
{
void Triangulate(
IntersectInfo const& intersect,
Fun3v const& grad,
Mesh& mesh);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

View File

@ -1,13 +0,0 @@
cmake_minimum_required(VERSION 3.15)
include(FetchContent)
set(BUILD_APPS OFF)
set(OPENMESH_DOCS OFF)
FetchContent_Declare(
OpenMesh
URL https://www.graphics.rwth-aachen.de/media/openmesh_static/Releases/8.1/OpenMesh-8.1.tar.gz
URL_HASH MD5=9e1eb6feeca3882ab95f9fc97681a4da)
FetchContent_MakeAvailable(OpenMesh)
target_compile_definitions(OpenMeshCoreStatic INTERFACE OM_STATIC_BUILD)

BIN
k.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

View File

@ -0,0 +1,75 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Defines
//
//=============================================================================
#ifndef OPENMESH_GEOMETRY_CONFIG_HH
#define OPENMESH_GEOMETRY_CONFIG_HH
//== INCLUDES =================================================================
// OpenMesh Namespace Defines
#include <OpenMesh/Core/System/config.h>
//== NAMESPACES ===============================================================
#define BEGIN_NS_GEOMETRY namespace geometry {
#define END_NS_GEOMETRY }
//=============================================================================
#endif // OPENMESH_GEOMETRY_CONFIG_HH defined
//=============================================================================

View File

@ -0,0 +1,196 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef LOOPSCHEMEMASKT_HH
#define LOOPSCHEMEMASKT_HH
#include <cmath>
#include <vector>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
namespace OpenMesh
{
/** implements cache for the weights of the original Loop scheme
supported:
- vertex projection rule on the next level
- vertex projection rule on the limit surface
- vertex projection rule on the k-th (level) step (Barthe, Kobbelt'2003)
- vertex tangents on the limit surface
*/
template <class T_, unsigned int cache_size_ = 100>
class LoopSchemeMaskT
{
public:
enum { cache_size = cache_size_ };
typedef T_ Scalar;
protected:
Scalar proj_weights_[cache_size];
Scalar limit_weights_[cache_size];
Scalar step_weights_[cache_size];
std::vector<Scalar> tang0_weights_[cache_size];
std::vector<Scalar> tang1_weights_[cache_size];
protected:
inline static Scalar compute_proj_weight(uint _valence)
{
//return pow(3.0 / 2.0 + cos(2.0 * M_PI / _valence), 2) / 2.0 - 1.0;
double denom = (3.0 + 2.0*cos(2.0*M_PI/(double)_valence));
double weight = (64.0*_valence)/(40.0 - denom*denom) - _valence;
return (Scalar) weight;
}
inline static Scalar compute_limit_weight(uint _valence)
{
double proj_weight = compute_proj_weight(_valence);
proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0));
return (Scalar)weight;
}
inline static Scalar compute_step_weight(uint _valence)
{
double proj_weight = compute_proj_weight(_valence);
proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
double weight = proj_weight - (3.0/8.0);
return (Scalar)weight;
}
inline static Scalar compute_tang0_weight(uint _valence, uint _ver_id)
{
return (Scalar)cos(2.0*M_PI*(double)_ver_id/(double)_valence);
}
inline static Scalar compute_tang1_weight(uint _valence, uint _ver_id)
{
return (Scalar)sin(2.0*M_PI*(double)_ver_id/(double)_valence);
}
void cache_weights()
{
proj_weights_[0] = 1;
for (uint k = 1; k < cache_size; ++k)
{
proj_weights_[k] = compute_proj_weight(k);
limit_weights_[k] = compute_limit_weight(k);
step_weights_[k] = compute_step_weight(k);
tang0_weights_[k].resize(k);
tang1_weights_[k].resize(k);
for (uint i = 0; i < k; ++i)
{
tang0_weights_[k][i] = compute_tang0_weight(k,i);
tang1_weights_[k][i] = compute_tang1_weight(k,i);
}
}
}
public:
LoopSchemeMaskT()
{
cache_weights();
}
inline Scalar proj_weight(uint _valence) const
{
assert(_valence < cache_size );
return proj_weights_[_valence];
}
inline Scalar limit_weight(uint _valence) const
{
assert(_valence < cache_size );
return limit_weights_[_valence];
}
inline Scalar step_weight(uint _valence, uint _step) const
{
assert(_valence < cache_size);
return pow(step_weights_[_valence], (int)_step);//can be precomputed
}
inline Scalar tang0_weight(uint _valence, uint _ver_id) const
{
assert(_valence < cache_size );
assert(_ver_id < _valence);
return tang0_weights_[_valence][_ver_id];
}
inline Scalar tang1_weight(uint _valence, uint _ver_id) const
{
assert(_valence < cache_size );
assert(_ver_id < _valence);
return tang1_weights_[_valence][_ver_id];
}
void dump(uint _max_valency = cache_size - 1) const
{
assert(_max_valency <= cache_size - 1);
//CConsole::printf("(k : pw_k, lw_k): ");
for (uint i = 0; i <= _max_valency; ++i)
{
//CConsole::stream() << "(" << i << " : " << proj_weight(i) << ", " << limit_weight(i) << ", " << step_weight(i,1) << "), ";
}
//CConsole::printf("\n");
}
};
typedef LoopSchemeMaskT<double, 100> LoopSchemeMaskDouble;
typedef SingletonT<LoopSchemeMaskDouble> LoopSchemeMaskDoubleSingleton;
}//namespace OpenMesh
#endif//LOOPSCHEMEMASKT_HH

View File

@ -0,0 +1,172 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef MATHDEFS_HH
#define MATHDEFS_HH
#include <cmath>
#include <cfloat>
#ifndef M_PI
#define M_PI 3.14159265359
#endif
namespace OpenMesh
{
/** comparison operators with user-selected precision control
*/
template <class T, typename Real>
inline bool is_zero(const T& _a, Real _eps)
{ return fabs(_a) < _eps; }
template <class T1, class T2, typename Real>
inline bool is_eq(const T1& a, const T2& b, Real _eps)
{ return is_zero(a-b, _eps); }
template <class T1, class T2, typename Real>
inline bool is_gt(const T1& a, const T2& b, Real _eps)
{ return (a > b) && !is_eq(a,b,_eps); }
template <class T1, class T2, typename Real>
inline bool is_ge(const T1& a, const T2& b, Real _eps)
{ return (a > b) || is_eq(a,b,_eps); }
template <class T1, class T2, typename Real>
inline bool is_lt(const T1& a, const T2& b, Real _eps)
{ return (a < b) && !is_eq(a,b,_eps); }
template <class T1, class T2, typename Real>
inline bool is_le(const T1& a, const T2& b, Real _eps)
{ return (a < b) || is_eq(a,b,_eps); }
/*const float flt_eps__ = 10*FLT_EPSILON;
const double dbl_eps__ = 10*DBL_EPSILON;*/
const float flt_eps__ = (float)1e-05;
const double dbl_eps__ = 1e-09;
inline float eps__(float)
{ return flt_eps__; }
inline double eps__(double)
{ return dbl_eps__; }
template <class T>
inline bool is_zero(const T& a)
{ return is_zero(a, eps__(a)); }
template <class T1, class T2>
inline bool is_eq(const T1& a, const T2& b)
{ return is_zero(a-b); }
template <class T1, class T2>
inline bool is_gt(const T1& a, const T2& b)
{ return (a > b) && !is_eq(a,b); }
template <class T1, class T2>
inline bool is_ge(const T1& a, const T2& b)
{ return (a > b) || is_eq(a,b); }
template <class T1, class T2>
inline bool is_lt(const T1& a, const T2& b)
{ return (a < b) && !is_eq(a,b); }
template <class T1, class T2>
inline bool is_le(const T1& a, const T2& b)
{ return (a < b) || is_eq(a,b); }
/// Trigonometry/angles - related
template <class T>
inline T sane_aarg(T _aarg)
{
if (_aarg < -1)
{
_aarg = -1;
}
else if (_aarg > 1)
{
_aarg = 1;
}
return _aarg;
}
/** returns the angle determined by its cos and the sign of its sin
result is positive if the angle is in [0:pi]
and negative if it is in [pi:2pi]
*/
template <class T>
T angle(T _cos_angle, T _sin_angle)
{//sanity checks - otherwise acos will return nan
_cos_angle = sane_aarg(_cos_angle);
return (T) _sin_angle >= 0 ? acos(_cos_angle) : -acos(_cos_angle);
}
template <class T>
inline T positive_angle(T _angle)
{ return _angle < 0 ? (2*M_PI + _angle) : _angle; }
template <class T>
inline T positive_angle(T _cos_angle, T _sin_angle)
{ return positive_angle(angle(_cos_angle, _sin_angle)); }
template <class T>
inline T deg_to_rad(const T& _angle)
{ return M_PI*(_angle/180); }
template <class T>
inline T rad_to_deg(const T& _angle)
{ return 180*(_angle/M_PI); }
inline double log_(double _value)
{ return log(_value); }
}//namespace OpenMesh
#endif//MATHDEFS_HH

View File

@ -0,0 +1,161 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS NormalConeT - IMPLEMENTATION
//
//=============================================================================
#define OPENMESH_NORMALCONE_C
//== INCLUDES =================================================================
#include <math.h>
#include "NormalConeT.hh"
#ifdef max
# undef max
#endif
#ifdef min
# undef min
#endif
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== IMPLEMENTATION ==========================================================
template <typename Scalar>
NormalConeT<Scalar>::
NormalConeT(const Vec3& _center_normal, Scalar _angle)
: center_normal_(_center_normal), angle_(_angle)
{
}
//----------------------------------------------------------------------------
template <typename Scalar>
Scalar
NormalConeT<Scalar>::
max_angle(const Vec3& _norm) const
{
Scalar dotp = (center_normal_ | _norm);
return (dotp >= 1.0 ? 0.0 : (dotp <= -1.0 ? M_PI : acos(dotp)))
+ angle_;
}
//----------------------------------------------------------------------------
template <typename Scalar>
Scalar
NormalConeT<Scalar>::
max_angle(const NormalConeT& _cone) const
{
Scalar dotp = (center_normal_ | _cone.center_normal_);
Scalar centerAngle = dotp >= 1.0 ? 0.0 : (dotp <= -1.0 ? M_PI : acos(dotp));
Scalar sideAngle0 = std::max(angle_-centerAngle, _cone.angle_);
Scalar sideAngle1 = std::max(_cone.angle_-centerAngle, angle_);
return centerAngle + sideAngle0 + sideAngle1;
}
//----------------------------------------------------------------------------
template <typename Scalar>
void
NormalConeT<Scalar>::
merge(const NormalConeT& _cone)
{
Scalar dotp = (center_normal_ | _cone.center_normal_);
if (fabs(dotp) < 0.99999f)
{
// new angle
Scalar centerAngle = acos(dotp);
Scalar minAngle = std::min(-angle(), centerAngle - _cone.angle());
Scalar maxAngle = std::max( angle(), centerAngle + _cone.angle());
angle_ = (maxAngle - minAngle) * Scalar(0.5f);
// axis by SLERP
Scalar axisAngle = Scalar(0.5f) * (minAngle + maxAngle);
center_normal_ = ((center_normal_ * sin(centerAngle-axisAngle)
+ _cone.center_normal_ * sin(axisAngle))
/ sin(centerAngle));
}
else
{
// axes point in same direction
if (dotp > 0.0f)
angle_ = std::max(angle_, _cone.angle_);
// axes point in opposite directions
else
angle_ = Scalar(2.0f * M_PI);
}
}
//=============================================================================
} // namespace OpenMesh
//=============================================================================

View File

@ -0,0 +1,132 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS NormalCone
//
//=============================================================================
#ifndef OPENMESH_NORMALCONE_HH
#define OPENMESH_NORMALCONE_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Geometry/VectorT.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/** /class NormalCone NormalCone.hh <ACG/Geometry/Types/NormalCone.hh>
NormalCone that can be merged with other normal cones. Provides
the center normal and the opening angle.
**/
template <typename Scalar>
class NormalConeT
{
public:
// typedefs
typedef VectorT<Scalar, 3> Vec3;
//! default constructor (not initialized)
NormalConeT() {}
//! Initialize cone with center (unit vector) and angle (radius in radians)
NormalConeT(const Vec3& _center_normal, Scalar _angle=0.0);
//! return max. distance (radians) unit vector to cone (distant side)
Scalar max_angle(const Vec3&) const;
//! return max. distance (radians) cone to cone (distant sides)
Scalar max_angle(const NormalConeT&) const;
//! merge _cone; this instance will then enclose both former cones
void merge(const NormalConeT&);
//! returns center normal
const Vec3& center_normal() const { return center_normal_; }
//! returns size of cone (radius in radians)
inline Scalar angle() const { return angle_; }
private:
Vec3 center_normal_;
Scalar angle_;
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_NORMALCONE_C)
#define OPENMESH_NORMALCONE_TEMPLATES
#include "NormalConeT.cc"
#endif
//=============================================================================
#endif // OPENMESH_NORMALCONE_HH defined
//=============================================================================

View File

@ -0,0 +1,124 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS Plane3D
//
//=============================================================================
#ifndef OPENMESH_PLANE3D_HH
#define OPENMESH_PLANE3D_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Geometry/VectorT.hh>
//== FORWARDDECLARATIONS ======================================================
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace VDPM {
//== CLASS DEFINITION =========================================================
/** \class Plane3d Plane3d.hh <OpenMesh/Tools/VDPM/Plane3d.hh>
ax + by + cz + d = 0
*/
class OPENMESHDLLEXPORT Plane3d
{
public:
typedef OpenMesh::Vec3f vector_type;
typedef vector_type::value_type value_type;
public:
Plane3d()
: d_(0)
{ }
Plane3d(const vector_type &_dir, const vector_type &_pnt)
: n_(_dir), d_(0)
{
n_.normalize();
d_ = -dot(n_,_pnt);
}
value_type signed_distance(const OpenMesh::Vec3f &_p)
{
return dot(n_ , _p) + d_;
}
// back compatibility
value_type singed_distance(const OpenMesh::Vec3f &point)
{ return signed_distance( point ); }
public:
vector_type n_;
value_type d_;
};
//=============================================================================
} // namespace VDPM
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_PLANE3D_HH defined
//=============================================================================

View File

@ -0,0 +1,291 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
/** \file Core/Geometry/QuadricT.hh
*/
//=============================================================================
//
// CLASS QuadricT
//
//=============================================================================
#ifndef OPENMESH_GEOMETRY_QUADRIC_HH
#define OPENMESH_GEOMETRY_QUADRIC_HH
//== INCLUDES =================================================================
#include "Config.hh"
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
//== NAMESPACE ================================================================
namespace OpenMesh { //BEGIN_NS_OPENMESH
namespace Geometry { //BEGIN_NS_GEOMETRY
//== CLASS DEFINITION =========================================================
/** /class QuadricT Geometry/QuadricT.hh
Stores a quadric as a 4x4 symmetrix matrix. Used by the
error quadric based mesh decimation algorithms.
**/
template <class Scalar>
class QuadricT
{
public:
typedef Scalar value_type;
typedef QuadricT<Scalar> type;
typedef QuadricT<Scalar> Self;
// typedef VectorInterface<Scalar, VecStorage3<Scalar> > Vec3;
// typedef VectorInterface<Scalar, VecStorage4<Scalar> > Vec4;
//typedef Vector3Elem Vec3;
//typedef Vector4Elem Vec4;
/// construct with upper triangle of symmetrix 4x4 matrix
QuadricT(Scalar _a, Scalar _b, Scalar _c, Scalar _d,
Scalar _e, Scalar _f, Scalar _g,
Scalar _h, Scalar _i,
Scalar _j)
: a_(_a), b_(_b), c_(_c), d_(_d),
e_(_e), f_(_f), g_(_g),
h_(_h), i_(_i),
j_(_j)
{
}
/// constructor from given plane equation: ax+by+cz+d_=0
QuadricT( Scalar _a=0.0, Scalar _b=0.0, Scalar _c=0.0, Scalar _d=0.0 )
: a_(_a*_a), b_(_a*_b), c_(_a*_c), d_(_a*_d),
e_(_b*_b), f_(_b*_c), g_(_b*_d),
h_(_c*_c), i_(_c*_d),
j_(_d*_d)
{}
template <class _Point>
QuadricT(const _Point& _pt)
{
set_distance_to_point(_pt);
}
template <class _Normal, class _Point>
QuadricT(const _Normal& _n, const _Point& _p)
{
set_distance_to_plane(_n,_p);
}
//set operator
void set(Scalar _a, Scalar _b, Scalar _c, Scalar _d,
Scalar _e, Scalar _f, Scalar _g,
Scalar _h, Scalar _i,
Scalar _j)
{
a_ = _a; b_ = _b; c_ = _c; d_ = _d;
e_ = _e; f_ = _f; g_ = _g;
h_ = _h; i_ = _i;
j_ = _j;
}
//sets the quadric representing the squared distance to _pt
template <class _Point>
void set_distance_to_point(const _Point& _pt)
{
set(1, 0, 0, -_pt[0],
1, 0, -_pt[1],
1, -_pt[2],
dot(_pt,_pt));
}
//sets the quadric representing the squared distance to the plane [_a,_b,_c,_d]
void set_distance_to_plane(Scalar _a, Scalar _b, Scalar _c, Scalar _d)
{
a_ = _a*_a; b_ = _a*_b; c_ = _a*_c; d_ = _a*_d;
e_ = _b*_b; f_ = _b*_c; g_ = _b*_d;
h_ = _c*_c; i_ = _c*_d;
j_ = _d*_d;
}
//sets the quadric representing the squared distance to the plane
//determined by the normal _n and the point _p
template <class _Normal, class _Point>
void set_distance_to_plane(const _Normal& _n, const _Point& _p)
{
set_distance_to_plane(_n[0], _n[1], _n[2], -dot(_n,_p));
}
/// set all entries to zero
void clear() { a_ = b_ = c_ = d_ = e_ = f_ = g_ = h_ = i_ = j_ = 0.0; }
/// add quadrics
QuadricT<Scalar>& operator+=( const QuadricT<Scalar>& _q )
{
a_ += _q.a_; b_ += _q.b_; c_ += _q.c_; d_ += _q.d_;
e_ += _q.e_; f_ += _q.f_; g_ += _q.g_;
h_ += _q.h_; i_ += _q.i_;
j_ += _q.j_;
return *this;
}
QuadricT<Scalar> operator+(const QuadricT<Scalar>& _other ) const
{
QuadricT<Scalar> result = *this;
return result += _other;
}
/// multiply by scalar
QuadricT<Scalar>& operator*=( Scalar _s)
{
a_ *= _s; b_ *= _s; c_ *= _s; d_ *= _s;
e_ *= _s; f_ *= _s; g_ *= _s;
h_ *= _s; i_ *= _s;
j_ *= _s;
return *this;
}
QuadricT<Scalar> operator*(Scalar _s) const
{
QuadricT<Scalar> result = *this;
return result *= _s;
}
/// multiply 4D vector from right: Q*v
template <class _Vec4>
_Vec4 operator*(const _Vec4& _v) const
{
Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]);
return _Vec4(x*a_ + y*b_ + z*c_ + w*d_,
x*b_ + y*e_ + z*f_ + w*g_,
x*c_ + y*f_ + z*h_ + w*i_,
x*d_ + y*g_ + z*i_ + w*j_);
}
/// evaluate quadric Q at (3D or 4D) vector v: v*Q*v
template <class _Vec>
Scalar operator()(const _Vec& _v) const
{
return evaluate(_v, GenProg::Int2Type<vector_traits<_Vec>::size_>());
}
Scalar a() const { return a_; }
Scalar b() const { return b_; }
Scalar c() const { return c_; }
Scalar d() const { return d_; }
Scalar e() const { return e_; }
Scalar f() const { return f_; }
Scalar g() const { return g_; }
Scalar h() const { return h_; }
Scalar i() const { return i_; }
Scalar j() const { return j_; }
Scalar xx() const { return a_; }
Scalar xy() const { return b_; }
Scalar xz() const { return c_; }
Scalar xw() const { return d_; }
Scalar yy() const { return e_; }
Scalar yz() const { return f_; }
Scalar yw() const { return g_; }
Scalar zz() const { return h_; }
Scalar zw() const { return i_; }
Scalar ww() const { return j_; }
protected:
/// evaluate quadric Q at 3D vector v: v*Q*v
template <class _Vec3>
Scalar evaluate(const _Vec3& _v, GenProg::Int2Type<3>/*_dimension*/) const
{
Scalar x(_v[0]), y(_v[1]), z(_v[2]);
return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x
+ e_*y*y + 2.0*f_*y*z + 2.0*g_*y
+ h_*z*z + 2.0*i_*z
+ j_;
}
/// evaluate quadric Q at 4D vector v: v*Q*v
template <class _Vec4>
Scalar evaluate(const _Vec4& _v, GenProg::Int2Type<4>/*_dimension*/) const
{
Scalar x(_v[0]), y(_v[1]), z(_v[2]), w(_v[3]);
return a_*x*x + 2.0*b_*x*y + 2.0*c_*x*z + 2.0*d_*x*w
+ e_*y*y + 2.0*f_*y*z + 2.0*g_*y*w
+ h_*z*z + 2.0*i_*z*w
+ j_*w*w;
}
private:
Scalar a_, b_, c_, d_,
e_, f_, g_,
h_, i_,
j_;
};
/// Quadric using floats
typedef QuadricT<float> Quadricf;
/// Quadric using double
typedef QuadricT<double> Quadricd;
//=============================================================================
} // END_NS_GEOMETRY
} // END_NS_OPENMESH
//============================================================================
#endif // OPENMESH_GEOMETRY_HH defined
//=============================================================================

View File

@ -0,0 +1,886 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
#ifndef OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_
#define OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_
#include <array>
#include <utility>
#include <algorithm>
#include <numeric>
#include <type_traits>
#include <cmath>
#include <ostream>
#include <istream>
#include <cassert>
#include <cstdlib>
// This header is not needed by this file but expected by others including
// this file.
#include <OpenMesh/Core/System/config.h>
/*
* Helpers for VectorT
*/
namespace {
template<typename ... Ts>
struct are_convertible_to;
template<typename To, typename From, typename ... Froms>
struct are_convertible_to<To, From, Froms...> {
static constexpr bool value = std::is_convertible<From, To>::value
&& are_convertible_to<To, Froms...>::value;
};
template<typename To, typename From>
struct are_convertible_to<To, From> : public std::is_convertible<From, To> {
};
}
namespace OpenMesh {
template<typename Scalar, int DIM>
class VectorT {
static_assert(DIM >= 1, "VectorT requires positive dimensionality.");
private:
using container = std::array<Scalar, DIM>;
container values_;
public:
//---------------------------------------------------------------- class info
/// the type of the scalar used in this template
typedef Scalar value_type;
/// type of this vector
typedef VectorT<Scalar, DIM> vector_type;
/// returns dimension of the vector (deprecated)
static constexpr int dim() {
return DIM;
}
/// returns dimension of the vector
static constexpr size_t size() {
return DIM;
}
static constexpr const size_t size_ = DIM;
//-------------------------------------------------------------- constructors
// Converting constructor: Constructs the vector from DIM values (of
// potentially heterogenous types) which are all convertible to Scalar.
template<typename T, typename ... Ts,
typename = typename std::enable_if<sizeof...(Ts)+1 == DIM>::type,
typename = typename std::enable_if<
are_convertible_to<Scalar, T, Ts...>::value>::type>
constexpr VectorT(T v, Ts... vs) : values_ { {static_cast<Scalar>(v), static_cast<Scalar>(vs)...} } {
static_assert(sizeof...(Ts)+1 == DIM,
"Invalid number of components specified in constructor.");
static_assert(are_convertible_to<Scalar, T, Ts...>::value,
"Not all components are convertible to Scalar.");
}
/// default constructor creates uninitialized values.
constexpr VectorT() {}
/**
* Creates a vector with all components set to v.
*/
explicit VectorT(const Scalar &v) {
vectorize(v);
}
VectorT(const VectorT &rhs) = default;
VectorT(VectorT &&rhs) = default;
VectorT &operator=(const VectorT &rhs) = default;
VectorT &operator=(VectorT &&rhs) = default;
/**
* Only for 4-component vectors with division operator on their
* Scalar: Dehomogenization.
*/
template<typename S = Scalar, int D = DIM>
auto homogenized() const ->
typename std::enable_if<D == 4,
VectorT<decltype(std::declval<S>()/std::declval<S>()), DIM>>::type {
static_assert(D == DIM, "D and DIM need to be identical. (Never "
"override the default template arguments.)");
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
return VectorT(
values_[0]/values_[3],
values_[1]/values_[3],
values_[2]/values_[3],
1);
}
/// construct from a value array or any other iterator
template<typename Iterator,
typename = decltype(
*std::declval<Iterator&>(), void(),
++std::declval<Iterator&>(), void())>
explicit VectorT(Iterator it) {
std::copy_n(it, DIM, values_.begin());
}
/// copy & cast constructor (explicit)
template<typename otherScalarType,
typename = typename std::enable_if<
std::is_convertible<otherScalarType, Scalar>::value>>
explicit VectorT(const VectorT<otherScalarType, DIM>& _rhs) {
operator=(_rhs);
}
//--------------------------------------------------------------------- casts
/// cast from vector with a different scalar type
template<typename OtherScalar,
typename = typename std::enable_if<
std::is_convertible<OtherScalar, Scalar>::value>>
vector_type& operator=(const VectorT<OtherScalar, DIM>& _rhs) {
std::transform(_rhs.cbegin(), _rhs.cend(),
this->begin(), [](OtherScalar rhs) {
return static_cast<Scalar>(std::move(rhs));
});
return *this;
}
/// access to Scalar array
Scalar* data() { return values_.data(); }
/// access to const Scalar array
const Scalar* data() const { return values_.data(); }
//----------------------------------------------------------- element access
/// get i'th element read-write
Scalar& operator[](size_t _i) {
assert(_i < DIM);
return values_[_i];
}
/// get i'th element read-only
const Scalar& operator[](size_t _i) const {
assert(_i < DIM);
return values_[_i];
}
//---------------------------------------------------------------- comparsion
/// component-wise comparison
bool operator==(const vector_type& _rhs) const {
return std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
}
/// component-wise comparison
bool operator!=(const vector_type& _rhs) const {
return !std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
}
//---------------------------------------------------------- scalar operators
/// component-wise self-multiplication with scalar
template<typename OtherScalar>
auto operator*=(const OtherScalar& _s) ->
typename std::enable_if<std::is_convertible<
decltype(this->values_[0] * _s), Scalar>::value,
VectorT<Scalar, DIM>&>::type {
for (auto& e : *this) {
e *= _s;
}
return *this;
}
/// component-wise self-division by scalar
template<typename OtherScalar>
auto operator/=(const OtherScalar& _s) ->
typename std::enable_if<std::is_convertible<
decltype(this->values_[0] / _s), Scalar>::value,
VectorT<Scalar, DIM>&>::type {
for (auto& e : *this) {
e /= _s;
}
return *this;
}
/// component-wise multiplication with scalar
template<typename OtherScalar>
typename std::enable_if<std::is_convertible<
decltype(std::declval<Scalar>() * std::declval<OtherScalar>()),
Scalar>::value,
VectorT<Scalar, DIM>>::type
operator*(const OtherScalar& _s) const {
return vector_type(*this) *= _s;
}
/// component-wise division by with scalar
template<typename OtherScalar>
typename std::enable_if<std::is_convertible<
decltype(std::declval<Scalar>() / std::declval<OtherScalar>()),
Scalar>::value,
VectorT<Scalar, DIM>>::type
operator/(const OtherScalar& _s) const {
return vector_type(*this) /= _s;
}
//---------------------------------------------------------- vector operators
/// component-wise self-multiplication
template<typename OtherScalar>
auto operator*=(const VectorT<OtherScalar, DIM>& _rhs) ->
typename std::enable_if<
sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
vector_type&>::type {
for (int i = 0; i < DIM; ++i) {
data()[i] *= _rhs.data()[i];
}
return *this;
}
/// component-wise self-division
template<typename OtherScalar>
auto operator/=(const VectorT<OtherScalar, DIM>& _rhs) ->
typename std::enable_if<
sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
vector_type&>::type {
for (int i = 0; i < DIM; ++i) {
data()[i] /= _rhs.data()[i];
}
return *this;
}
/// vector difference from this
template<typename OtherScalar>
auto operator-=(const VectorT<OtherScalar, DIM>& _rhs) ->
typename std::enable_if<
sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
vector_type&>::type {
for (int i = 0; i < DIM; ++i) {
data()[i] -= _rhs.data()[i];
}
return *this;
}
/// vector self-addition
template<typename OtherScalar>
auto operator+=(const VectorT<OtherScalar, DIM>& _rhs) ->
typename std::enable_if<
sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
vector_type&>::type {
for (int i = 0; i < DIM; ++i) {
data()[i] += _rhs.data()[i];
}
return *this;
}
/// component-wise vector multiplication
template<typename OtherScalar>
auto operator*(const VectorT<OtherScalar, DIM>& _rhs) const ->
typename std::enable_if<
sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
vector_type>::type {
return vector_type(*this) *= _rhs;
}
/// component-wise vector division
template<typename OtherScalar>
auto operator/(const VectorT<OtherScalar, DIM>& _rhs) const ->
typename std::enable_if<
sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
vector_type>::type {
return vector_type(*this) /= _rhs;
}
/// component-wise vector addition
template<typename OtherScalar>
auto operator+(const VectorT<OtherScalar, DIM>& _rhs) const ->
typename std::enable_if<
sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
vector_type>::type {
return vector_type(*this) += _rhs;
}
/// component-wise vector difference
template<typename OtherScalar>
auto operator-(const VectorT<OtherScalar, DIM>& _rhs) const ->
typename std::enable_if<
sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
vector_type>::type {
return vector_type(*this) -= _rhs;
}
/// unary minus
vector_type operator-(void) const {
vector_type v;
std::transform(values_.begin(), values_.end(), v.values_.begin(),
[](const Scalar &s) { return -s; });
return v;
}
/// cross product: only defined for Vec3* as specialization
/// \see OpenMesh::cross
template<typename OtherScalar>
auto operator% (const VectorT<OtherScalar, DIM> &_rhs) const ->
typename std::enable_if<DIM == 3,
VectorT<decltype((*this)[0] * _rhs[0] -
(*this)[0] * _rhs[0]), DIM>>::type {
return {
values_[1] * _rhs[2] - values_[2] * _rhs[1],
values_[2] * _rhs[0] - values_[0] * _rhs[2],
values_[0] * _rhs[1] - values_[1] * _rhs[0]
};
}
/// compute scalar product
/// \see OpenMesh::dot
template<typename OtherScalar>
auto operator|(const VectorT<OtherScalar, DIM>& _rhs) const ->
decltype(*this->data() * *_rhs.data()) {
return std::inner_product(begin() + 1, begin() + DIM, _rhs.begin() + 1,
*begin() * *_rhs.begin());
}
//------------------------------------------------------------ euclidean norm
/// \name Euclidean norm calculations
//@{
/// compute squared euclidean norm
template<typename S = Scalar>
decltype(std::declval<S>() * std::declval<S>()) sqrnorm() const {
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
typedef decltype(values_[0] * values_[0]) RESULT;
return std::accumulate(values_.cbegin() + 1, values_.cend(),
values_[0] * values_[0],
[](const RESULT &l, const Scalar &r) { return l + r * r; });
}
/// compute euclidean norm
template<typename S = Scalar>
auto norm() const ->
decltype(std::sqrt(std::declval<VectorT<S, DIM>>().sqrnorm())) {
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
return std::sqrt(sqrnorm());
}
template<typename S = Scalar>
auto length() const ->
decltype(std::declval<VectorT<S, DIM>>().norm()) {
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
return norm();
}
/** normalize vector, return normalized vector
*/
template<typename S = Scalar>
auto normalize() ->
decltype(*this /= std::declval<VectorT<S, DIM>>().norm()) {
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
return *this /= norm();
}
/** return normalized vector
*/
template<typename S = Scalar>
auto normalized() const ->
decltype(*this / std::declval<VectorT<S, DIM>>().norm()) {
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
return *this / norm();
}
/** normalize vector, return normalized vector and avoids div by zero
*/
template<typename S = Scalar>
typename std::enable_if<
sizeof(decltype(
static_cast<S>(0),
std::declval<VectorT<S, DIM>>().norm())) >= 0,
vector_type&>::type
normalize_cond() {
static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
"to be the same type. (Never override the default template "
"arguments.)");
auto n = norm();
if (n != static_cast<decltype(norm())>(0)) {
*this /= n;
}
return *this;
}
//@}
//------------------------------------------------------------ euclidean norm
/// \name Non-Euclidean norm calculations
//@{
/// compute L1 (Manhattan) norm
Scalar l1_norm() const {
return std::accumulate(
values_.cbegin() + 1, values_.cend(), values_[0]);
}
/// compute l8_norm
Scalar l8_norm() const {
return max_abs();
}
//@}
//------------------------------------------------------------ max, min, mean
/// \name Minimum maximum and mean
//@{
/// return the maximal component
Scalar max() const {
return *std::max_element(values_.cbegin(), values_.cend());
}
/// return the maximal absolute component
Scalar max_abs() const {
return std::abs(
*std::max_element(values_.cbegin(), values_.cend(),
[](const Scalar &a, const Scalar &b) {
return std::abs(a) < std::abs(b);
}));
}
/// return the minimal component
Scalar min() const {
return *std::min_element(values_.cbegin(), values_.cend());
}
/// return the minimal absolute component
Scalar min_abs() const {
return std::abs(
*std::min_element(values_.cbegin(), values_.cend(),
[](const Scalar &a, const Scalar &b) {
return std::abs(a) < std::abs(b);
}));
}
/// return arithmetic mean
Scalar mean() const {
return l1_norm()/DIM;
}
/// return absolute arithmetic mean
Scalar mean_abs() const {
return std::accumulate(values_.cbegin() + 1, values_.cend(),
std::abs(values_[0]),
[](const Scalar &l, const Scalar &r) {
return l + std::abs(r);
}) / DIM;
}
/// minimize values: same as *this = min(*this, _rhs), but faster
vector_type& minimize(const vector_type& _rhs) {
std::transform(values_.cbegin(), values_.cend(),
_rhs.values_.cbegin(),
values_.begin(),
[](const Scalar &l, const Scalar &r) {
return std::min(l, r);
});
return *this;
}
/// minimize values and signalize coordinate minimization
bool minimized(const vector_type& _rhs) {
bool result = false;
std::transform(values_.cbegin(), values_.cend(),
_rhs.values_.cbegin(),
values_.begin(),
[&result](const Scalar &l, const Scalar &r) {
if (l < r) {
return l;
} else {
result = true;
return r;
}
});
return result;
}
/// maximize values: same as *this = max(*this, _rhs), but faster
vector_type& maximize(const vector_type& _rhs) {
std::transform(values_.cbegin(), values_.cend(),
_rhs.values_.cbegin(),
values_.begin(),
[](const Scalar &l, const Scalar &r) {
return std::max(l, r);
});
return *this;
}
/// maximize values and signalize coordinate maximization
bool maximized(const vector_type& _rhs) {
bool result = false;
std::transform(values_.cbegin(), values_.cend(),
_rhs.values_.cbegin(),
values_.begin(),
[&result](const Scalar &l, const Scalar &r) {
if (l > r) {
return l;
} else {
result = true;
return r;
}
});
return result;
}
/// component-wise min
inline vector_type min(const vector_type& _rhs) const {
return vector_type(*this).minimize(_rhs);
}
/// component-wise max
inline vector_type max(const vector_type& _rhs) const {
return vector_type(*this).maximize(_rhs);
}
//@}
//------------------------------------------------------------ misc functions
/// component-wise apply function object with Scalar operator()(Scalar).
template<typename Functor>
inline vector_type apply(const Functor& _func) const {
vector_type result;
std::transform(result.values_.cbegin(), result.values_.cend(),
result.values_.begin(), _func);
return result;
}
/// store the same value in each component (e.g. to clear all entries)
vector_type& vectorize(const Scalar& _s) {
std::fill(values_.begin(), values_.end(), _s);
return *this;
}
/// store the same value in each component
static vector_type vectorized(const Scalar& _s) {
return vector_type().vectorize(_s);
}
/// lexicographical comparison
bool operator<(const vector_type& _rhs) const {
return std::lexicographical_compare(
values_.begin(), values_.end(),
_rhs.values_.begin(), _rhs.values_.end());
}
/// swap with another vector
void swap(VectorT& _other)
noexcept(noexcept(std::swap(values_, _other.values_))) {
std::swap(values_, _other.values_);
}
//------------------------------------------------------------ component iterators
/// \name Component iterators
//@{
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
using reverse_iterator = typename container::reverse_iterator;
using const_reverse_iterator = typename container::const_reverse_iterator;
iterator begin() noexcept { return values_.begin(); }
const_iterator begin() const noexcept { return values_.cbegin(); }
const_iterator cbegin() const noexcept { return values_.cbegin(); }
iterator end() noexcept { return values_.end(); }
const_iterator end() const noexcept { return values_.cend(); }
const_iterator cend() const noexcept { return values_.cend(); }
reverse_iterator rbegin() noexcept { return values_.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return values_.crbegin(); }
const_reverse_iterator crbegin() const noexcept { return values_.crbegin(); }
reverse_iterator rend() noexcept { return values_.rend(); }
const_reverse_iterator rend() const noexcept { return values_.crend(); }
const_reverse_iterator crend() const noexcept { return values_.crend(); }
//@}
};
/// Component wise multiplication from the left
template<typename Scalar, int DIM, typename OtherScalar>
auto operator*(const OtherScalar& _s, const VectorT<Scalar, DIM> &rhs) ->
decltype(rhs.operator*(_s)) {
return rhs * _s;
}
/// output a vector by printing its space-separated compontens
template<typename Scalar, int DIM>
auto operator<<(std::ostream& os, const VectorT<Scalar, DIM> &_vec) ->
typename std::enable_if<
sizeof(decltype(os << _vec[0])) >= 0, std::ostream&>::type {
os << _vec[0];
for (int i = 1; i < DIM; ++i) {
os << " " << _vec[i];
}
return os;
}
/// read the space-separated components of a vector from a stream
template<typename Scalar, int DIM>
auto operator>> (std::istream& is, VectorT<Scalar, DIM> &_vec) ->
typename std::enable_if<
sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type {
for (int i = 0; i < DIM; ++i)
is >> _vec[i];
return is;
}
/// \relates OpenMesh::VectorT
/// symmetric version of the dot product
template<typename Scalar, int DIM>
Scalar dot(const VectorT<Scalar, DIM>& _v1, const VectorT<Scalar, DIM>& _v2) {
return (_v1 | _v2);
}
/// \relates OpenMesh::VectorT
/// symmetric version of the cross product
template<typename LScalar, typename RScalar, int DIM>
auto
cross(const VectorT<LScalar, DIM>& _v1, const VectorT<RScalar, DIM>& _v2) ->
decltype(_v1 % _v2) {
return (_v1 % _v2);
}
/// \relates OpenMesh::VectorT
/// non-member swap
template<typename Scalar, int DIM>
void swap(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2)
noexcept(noexcept(_v1.swap(_v2))) {
_v1.swap(_v2);
}
/// \relates OpenMesh::VectorT
/// non-member norm
template<typename Scalar, int DIM>
Scalar norm(const VectorT<Scalar, DIM>& _v) {
return _v.norm();
}
/// \relates OpenMesh::VectorT
/// non-member sqrnorm
template<typename Scalar, int DIM>
Scalar sqrnorm(const VectorT<Scalar, DIM>& _v) {
return _v.sqrnorm();
}
/// \relates OpenMesh::VectorT
/// non-member vectorize
template<typename Scalar, int DIM, typename OtherScalar>
VectorT<Scalar, DIM>& vectorize(VectorT<Scalar, DIM>& _v, OtherScalar const& _val) {
return _v.vectorize(_val);
}
/// \relates OpenMesh::VectorT
/// non-member normalize
template<typename Scalar, int DIM>
VectorT<Scalar, DIM>& normalize(VectorT<Scalar, DIM>& _v) {
return _v.normalize();
}
/// \relates OpenMesh::VectorT
/// non-member maximize
template<typename Scalar, int DIM>
VectorT<Scalar, DIM>& maximize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
return _v1.maximize(_v2);
}
/// \relates OpenMesh::VectorT
/// non-member minimize
template<typename Scalar, int DIM>
VectorT<Scalar, DIM>& minimize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
return _v1.minimize(_v2);
}
//== TYPEDEFS =================================================================
/** 1-byte signed vector */
typedef VectorT<signed char,1> Vec1c;
/** 1-byte unsigned vector */
typedef VectorT<unsigned char,1> Vec1uc;
/** 1-short signed vector */
typedef VectorT<signed short int,1> Vec1s;
/** 1-short unsigned vector */
typedef VectorT<unsigned short int,1> Vec1us;
/** 1-int signed vector */
typedef VectorT<signed int,1> Vec1i;
/** 1-int unsigned vector */
typedef VectorT<unsigned int,1> Vec1ui;
/** 1-float vector */
typedef VectorT<float,1> Vec1f;
/** 1-double vector */
typedef VectorT<double,1> Vec1d;
/** 2-byte signed vector */
typedef VectorT<signed char,2> Vec2c;
/** 2-byte unsigned vector */
typedef VectorT<unsigned char,2> Vec2uc;
/** 2-short signed vector */
typedef VectorT<signed short int,2> Vec2s;
/** 2-short unsigned vector */
typedef VectorT<unsigned short int,2> Vec2us;
/** 2-int signed vector */
typedef VectorT<signed int,2> Vec2i;
/** 2-int unsigned vector */
typedef VectorT<unsigned int,2> Vec2ui;
/** 2-float vector */
typedef VectorT<float,2> Vec2f;
/** 2-double vector */
typedef VectorT<double,2> Vec2d;
/** 3-byte signed vector */
typedef VectorT<signed char,3> Vec3c;
/** 3-byte unsigned vector */
typedef VectorT<unsigned char,3> Vec3uc;
/** 3-short signed vector */
typedef VectorT<signed short int,3> Vec3s;
/** 3-short unsigned vector */
typedef VectorT<unsigned short int,3> Vec3us;
/** 3-int signed vector */
typedef VectorT<signed int,3> Vec3i;
/** 3-int unsigned vector */
typedef VectorT<unsigned int,3> Vec3ui;
/** 3-float vector */
typedef VectorT<float,3> Vec3f;
/** 3-double vector */
typedef VectorT<double,3> Vec3d;
/** 3-bool vector */
typedef VectorT<bool,3> Vec3b;
/** 4-byte signed vector */
typedef VectorT<signed char,4> Vec4c;
/** 4-byte unsigned vector */
typedef VectorT<unsigned char,4> Vec4uc;
/** 4-short signed vector */
typedef VectorT<signed short int,4> Vec4s;
/** 4-short unsigned vector */
typedef VectorT<unsigned short int,4> Vec4us;
/** 4-int signed vector */
typedef VectorT<signed int,4> Vec4i;
/** 4-int unsigned vector */
typedef VectorT<unsigned int,4> Vec4ui;
/** 4-float vector */
typedef VectorT<float,4> Vec4f;
/** 4-double vector */
typedef VectorT<double,4> Vec4d;
/** 5-byte signed vector */
typedef VectorT<signed char, 5> Vec5c;
/** 5-byte unsigned vector */
typedef VectorT<unsigned char, 5> Vec5uc;
/** 5-short signed vector */
typedef VectorT<signed short int, 5> Vec5s;
/** 5-short unsigned vector */
typedef VectorT<unsigned short int, 5> Vec5us;
/** 5-int signed vector */
typedef VectorT<signed int, 5> Vec5i;
/** 5-int unsigned vector */
typedef VectorT<unsigned int, 5> Vec5ui;
/** 5-float vector */
typedef VectorT<float, 5> Vec5f;
/** 5-double vector */
typedef VectorT<double, 5> Vec5d;
/** 6-byte signed vector */
typedef VectorT<signed char,6> Vec6c;
/** 6-byte unsigned vector */
typedef VectorT<unsigned char,6> Vec6uc;
/** 6-short signed vector */
typedef VectorT<signed short int,6> Vec6s;
/** 6-short unsigned vector */
typedef VectorT<unsigned short int,6> Vec6us;
/** 6-int signed vector */
typedef VectorT<signed int,6> Vec6i;
/** 6-int unsigned vector */
typedef VectorT<unsigned int,6> Vec6ui;
/** 6-float vector */
typedef VectorT<float,6> Vec6f;
/** 6-double vector */
typedef VectorT<double,6> Vec6d;
} // namespace OpenMesh
/**
* Literal operator for inline specification of colors in HTML syntax.
*
* Example:
* \code{.cpp}
* OpenMesh::Vec4f light_blue = 0x1FCFFFFF_htmlColor;
* \endcode
*/
constexpr OpenMesh::Vec4f operator"" _htmlColor(unsigned long long raw_color) {
return OpenMesh::Vec4f(
((raw_color >> 24) & 0xFF) / 255.0f,
((raw_color >> 16) & 0xFF) / 255.0f,
((raw_color >> 8) & 0xFF) / 255.0f,
((raw_color >> 0) & 0xFF) / 255.0f);
}
#endif /* OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_ */

View File

@ -0,0 +1,440 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS VectorT
//
//=============================================================================
// Don't parse this header file with doxygen since
// for some reason (obviously due to a bug in doxygen,
// bugreport: https://bugzilla.gnome.org/show_bug.cgi?id=629182)
// macro expansion and preprocessor defines
// don't work properly.
#if ((defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(OPENMESH_VECTOR_LEGACY)
#include "Vector11T.hh"
#else
#ifndef DOXYGEN
#ifndef OPENMESH_VECTOR_HH
#define OPENMESH_VECTOR_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <ostream>
#include <cmath>
#include <cassert>
#include <cstring>
#if defined(__GNUC__) && defined(__SSE__)
#include <xmmintrin.h>
#endif
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/** The N values of the template Scalar type are the only data members
of the class VectorT<Scalar,N>. This guarantees 100% compatibility
with arrays of type Scalar and size N, allowing us to define the
cast operators to and from arrays and array pointers.
In addition, this class will be specialized for Vec4f to be 16 bit
aligned, so that aligned SSE instructions can be used on these
vectors.
*/
template<typename Scalar, int N> class VectorDataT {
public:
Scalar values_[N];
};
#if defined(__GNUC__) && defined(__SSE__)
/// This specialization enables us to use aligned SSE instructions.
template<> class VectorDataT<float, 4> {
public:
union {
__m128 m128;
float values_[4];
};
};
#endif
//== CLASS DEFINITION =========================================================
#define DIM N
#define TEMPLATE_HEADER template <typename Scalar, int N>
#define CLASSNAME VectorT
#define DERIVED VectorDataT<Scalar,N>
#define unroll(expr) for (int i=0; i<N; ++i) expr(i)
/** \class VectorT VectorT.hh <OpenMesh/Core/Math/VectorT.hh>
A vector is an array of \<N\> values of type \<Scalar\>.
The actual data is stored in an VectorDataT, this class just adds
the necessary operators.
*/
#include "VectorT_inc.hh"
#undef DIM
#undef TEMPLATE_HEADER
#undef CLASSNAME
#undef DERIVED
#undef unroll
//== PARTIAL TEMPLATE SPECIALIZATIONS =========================================
#if OM_PARTIAL_SPECIALIZATION
#define TEMPLATE_HEADER template <typename Scalar>
#define CLASSNAME VectorT<Scalar,DIM>
#define DERIVED VectorDataT<Scalar,DIM>
#define DIM 2
#define unroll(expr) expr(0) expr(1)
#define unroll_comb(expr, op) expr(0) op expr(1)
#define unroll_csv(expr) expr(0), expr(1)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#define DIM 3
#define unroll(expr) expr(0) expr(1) expr(2)
#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2)
#define unroll_csv(expr) expr(0), expr(1), expr(2)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#define DIM 4
#define unroll(expr) expr(0) expr(1) expr(2) expr(3)
#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3)
#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#define DIM 5
#define unroll(expr) expr(0) expr(1) expr(2) expr(3) expr(4)
#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3) op expr(4)
#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3), expr(4)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#define DIM 6
#define unroll(expr) expr(0) expr(1) expr(2) expr(3) expr(4) expr(5)
#define unroll_comb(expr, op) expr(0) op expr(1) op expr(2) op expr(3) op expr(4) op expr(5)
#define unroll_csv(expr) expr(0), expr(1), expr(2), expr(3), expr(4), expr(5)
#include "VectorT_inc.hh"
#undef DIM
#undef unroll
#undef unroll_comb
#undef unroll_csv
#undef TEMPLATE_HEADER
#undef CLASSNAME
#undef DERIVED
//== FULL TEMPLATE SPECIALIZATIONS ============================================
#else
/// cross product for Vec3f
template<>
inline VectorT<float,3>
VectorT<float,3>::operator%(const VectorT<float,3>& _rhs) const
{
return
VectorT<float,3>(values_[1]*_rhs.values_[2]-values_[2]*_rhs.values_[1],
values_[2]*_rhs.values_[0]-values_[0]*_rhs.values_[2],
values_[0]*_rhs.values_[1]-values_[1]*_rhs.values_[0]);
}
/// cross product for Vec3d
template<>
inline VectorT<double,3>
VectorT<double,3>::operator%(const VectorT<double,3>& _rhs) const
{
return
VectorT<double,3>(values_[1]*_rhs.values_[2]-values_[2]*_rhs.values_[1],
values_[2]*_rhs.values_[0]-values_[0]*_rhs.values_[2],
values_[0]*_rhs.values_[1]-values_[1]*_rhs.values_[0]);
}
#endif
//== GLOBAL FUNCTIONS =========================================================
/// \relates OpenMesh::VectorT
/// scalar * vector
template<typename Scalar1, typename Scalar2,int N>
inline VectorT<Scalar1,N> operator*(Scalar2 _s, const VectorT<Scalar1,N>& _v) {
return _v*_s;
}
/// \relates OpenMesh::VectorT
/// symmetric version of the dot product
template<typename Scalar, int N>
inline Scalar
dot(const VectorT<Scalar,N>& _v1, const VectorT<Scalar,N>& _v2) {
return (_v1 | _v2);
}
/// \relates OpenMesh::VectorT
/// symmetric version of the cross product
template<typename Scalar, int N>
inline VectorT<Scalar,N>
cross(const VectorT<Scalar,N>& _v1, const VectorT<Scalar,N>& _v2) {
return (_v1 % _v2);
}
/// \relates OpenMesh::VectorT
/// non-member norm
template<typename Scalar, int DIM>
Scalar norm(const VectorT<Scalar, DIM>& _v) {
return _v.norm();
}
/// \relates OpenMesh::VectorT
/// non-member sqrnorm
template<typename Scalar, int DIM>
Scalar sqrnorm(const VectorT<Scalar, DIM>& _v) {
return _v.sqrnorm();
}
/// \relates OpenMesh::VectorT
/// non-member vectorize
template<typename Scalar, int DIM, typename OtherScalar>
VectorT<Scalar, DIM>& vectorize(VectorT<Scalar, DIM>& _v, OtherScalar const& _val) {
return _v.vectorize(_val);
}
/// \relates OpenMesh::VectorT
/// non-member normalize
template<typename Scalar, int DIM>
VectorT<Scalar, DIM>& normalize(VectorT<Scalar, DIM>& _v) {
return _v.normalize();
}
/// \relates OpenMesh::VectorT
/// non-member maximize
template<typename Scalar, int DIM>
VectorT<Scalar, DIM>& maximize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
return _v1.maximize(_v2);
}
/// \relates OpenMesh::VectorT
/// non-member minimize
template<typename Scalar, int DIM>
VectorT<Scalar, DIM>& minimize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
return _v1.minimize(_v2);
}
//== TYPEDEFS =================================================================
/** 1-byte signed vector */
typedef VectorT<signed char,1> Vec1c;
/** 1-byte unsigned vector */
typedef VectorT<unsigned char,1> Vec1uc;
/** 1-short signed vector */
typedef VectorT<signed short int,1> Vec1s;
/** 1-short unsigned vector */
typedef VectorT<unsigned short int,1> Vec1us;
/** 1-int signed vector */
typedef VectorT<signed int,1> Vec1i;
/** 1-int unsigned vector */
typedef VectorT<unsigned int,1> Vec1ui;
/** 1-float vector */
typedef VectorT<float,1> Vec1f;
/** 1-double vector */
typedef VectorT<double,1> Vec1d;
/** 2-byte signed vector */
typedef VectorT<signed char,2> Vec2c;
/** 2-byte unsigned vector */
typedef VectorT<unsigned char,2> Vec2uc;
/** 2-short signed vector */
typedef VectorT<signed short int,2> Vec2s;
/** 2-short unsigned vector */
typedef VectorT<unsigned short int,2> Vec2us;
/** 2-int signed vector */
typedef VectorT<signed int,2> Vec2i;
/** 2-int unsigned vector */
typedef VectorT<unsigned int,2> Vec2ui;
/** 2-float vector */
typedef VectorT<float,2> Vec2f;
/** 2-double vector */
typedef VectorT<double,2> Vec2d;
/** 3-byte signed vector */
typedef VectorT<signed char,3> Vec3c;
/** 3-byte unsigned vector */
typedef VectorT<unsigned char,3> Vec3uc;
/** 3-short signed vector */
typedef VectorT<signed short int,3> Vec3s;
/** 3-short unsigned vector */
typedef VectorT<unsigned short int,3> Vec3us;
/** 3-int signed vector */
typedef VectorT<signed int,3> Vec3i;
/** 3-int unsigned vector */
typedef VectorT<unsigned int,3> Vec3ui;
/** 3-float vector */
typedef VectorT<float,3> Vec3f;
/** 3-double vector */
typedef VectorT<double,3> Vec3d;
/** 3-bool vector */
typedef VectorT<bool,3> Vec3b;
/** 4-byte signed vector */
typedef VectorT<signed char,4> Vec4c;
/** 4-byte unsigned vector */
typedef VectorT<unsigned char,4> Vec4uc;
/** 4-short signed vector */
typedef VectorT<signed short int,4> Vec4s;
/** 4-short unsigned vector */
typedef VectorT<unsigned short int,4> Vec4us;
/** 4-int signed vector */
typedef VectorT<signed int,4> Vec4i;
/** 4-int unsigned vector */
typedef VectorT<unsigned int,4> Vec4ui;
/** 4-float vector */
typedef VectorT<float,4> Vec4f;
/** 4-double vector */
typedef VectorT<double,4> Vec4d;
/** 5-byte signed vector */
typedef VectorT<signed char, 5> Vec5c;
/** 5-byte unsigned vector */
typedef VectorT<unsigned char, 5> Vec5uc;
/** 5-short signed vector */
typedef VectorT<signed short int, 5> Vec5s;
/** 5-short unsigned vector */
typedef VectorT<unsigned short int, 5> Vec5us;
/** 5-int signed vector */
typedef VectorT<signed int, 5> Vec5i;
/** 5-int unsigned vector */
typedef VectorT<unsigned int, 5> Vec5ui;
/** 5-float vector */
typedef VectorT<float, 5> Vec5f;
/** 5-double vector */
typedef VectorT<double, 5> Vec5d;
/** 6-byte signed vector */
typedef VectorT<signed char,6> Vec6c;
/** 6-byte unsigned vector */
typedef VectorT<unsigned char,6> Vec6uc;
/** 6-short signed vector */
typedef VectorT<signed short int,6> Vec6s;
/** 6-short unsigned vector */
typedef VectorT<unsigned short int,6> Vec6us;
/** 6-int signed vector */
typedef VectorT<signed int,6> Vec6i;
/** 6-int unsigned vector */
typedef VectorT<unsigned int,6> Vec6ui;
/** 6-float vector */
typedef VectorT<float,6> Vec6f;
/** 6-double vector */
typedef VectorT<double,6> Vec6d;
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_VECTOR_HH defined
//=============================================================================
#endif // DOXYGEN
#endif // C++11

View File

@ -0,0 +1,668 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
// Set template keywords and class names properly when
// parsing with doxygen. This only seems to work this way since
// the scope of preprocessor defines is limited to one file in doxy.
#ifdef DOXYGEN
// Only used for correct doxygen parsing
#define OPENMESH_VECTOR_HH
#define DIM N
#define TEMPLATE_HEADER template <typename Scalar, int N>
#define CLASSNAME VectorT
#define DERIVED VectorDataT<Scalar,N>
#define unroll(expr) for (int i=0; i<N; ++i) expr(i)
#endif
#if defined( OPENMESH_VECTOR_HH )
// ----------------------------------------------------------------------------
TEMPLATE_HEADER
class CLASSNAME : public DERIVED
{
private:
typedef DERIVED Base;
public:
//---------------------------------------------------------------- class info
/// the type of the scalar used in this template
typedef Scalar value_type;
/// type of this vector
typedef VectorT<Scalar,DIM> vector_type;
/// returns dimension of the vector (deprecated)
static inline int dim() { return DIM; }
/// returns dimension of the vector
static inline size_t size() { return DIM; }
static const size_t size_ = DIM;
//-------------------------------------------------------------- constructors
/// default constructor creates uninitialized values.
inline VectorT() {}
/// special constructor for 1D vectors
explicit inline VectorT(const Scalar& v) {
// assert(DIM==1);
// values_[0] = v0;
vectorize(v);
}
#if DIM == 2
/// special constructor for 2D vectors
inline VectorT(const Scalar v0, const Scalar v1) {
Base::values_[0] = v0; Base::values_[1] = v1;
}
#endif
#if DIM == 3
/// special constructor for 3D vectors
inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2) {
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
}
#endif
#if DIM == 4
/// special constructor for 4D vectors
inline VectorT(const Scalar v0, const Scalar v1,
const Scalar v2, const Scalar v3) {
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
}
VectorT homogenized() const { return VectorT(Base::values_[0]/Base::values_[3], Base::values_[1]/Base::values_[3], Base::values_[2]/Base::values_[3], 1); }
#endif
#if DIM == 5
/// special constructor for 5D vectors
inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2,
const Scalar v3, const Scalar v4) {
Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
}
#endif
#if DIM == 6
/// special constructor for 6D vectors
inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2,
const Scalar v3, const Scalar v4, const Scalar v5) {
Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
}
#endif
/// construct from a value array (explicit)
explicit inline VectorT(const Scalar _values[DIM]) {
memcpy(data(), _values, DIM*sizeof(Scalar));
}
#ifdef OM_CC_MIPS
/// assignment from a vector of the same kind
// mipspro need this method
inline vector_type& operator=(const vector_type& _rhs) {
memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
return *this;
}
#endif
/// copy & cast constructor (explicit)
template<typename otherScalarType>
explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
operator=(_rhs);
}
//--------------------------------------------------------------------- casts
/// cast from vector with a different scalar type
template<typename otherScalarType>
inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
#define expr(i) Base::values_[i] = (Scalar)_rhs[i];
unroll(expr);
#undef expr
return *this;
}
// /// cast to Scalar array
// inline operator Scalar*() { return Base::values_; }
// /// cast to const Scalar array
// inline operator const Scalar*() const { return Base::values_; }
/// access to Scalar array
inline Scalar* data() { return Base::values_; }
/// access to const Scalar array
inline const Scalar*data() const { return Base::values_; }
//----------------------------------------------------------- element access
// /// get i'th element read-write
// inline Scalar& operator[](int _i) {
// assert(_i>=0 && _i<DIM); return Base::values_[_i];
// }
// /// get i'th element read-only
// inline const Scalar& operator[](int _i) const {
// assert(_i>=0 && _i<DIM); return Base::values_[_i];
// }
/// get i'th element read-write
inline Scalar& operator[](size_t _i) {
assert(_i<DIM); return Base::values_[_i];
}
/// get i'th element read-only
inline const Scalar& operator[](size_t _i) const {
assert(_i<DIM); return Base::values_[_i];
}
//---------------------------------------------------------------- comparsion
/// component-wise comparison
inline bool operator==(const vector_type& _rhs) const {
#define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
unroll(expr);
#undef expr
return true;
}
/// component-wise comparison
inline bool operator!=(const vector_type& _rhs) const {
return !(*this == _rhs);
}
//---------------------------------------------------------- scalar operators
/// component-wise self-multiplication with scalar
inline vector_type& operator*=(const Scalar& _s) {
#define expr(i) Base::values_[i] *= _s;
unroll(expr);
#undef expr
return *this;
}
/** component-wise self-division by scalar
\attention v *= (1/_s) is much faster than this */
inline vector_type& operator/=(const Scalar& _s) {
#define expr(i) Base::values_[i] /= _s;
unroll(expr);
#undef expr
return *this;
}
/// component-wise multiplication with scalar
inline vector_type operator*(const Scalar& _s) const {
#if DIM==N
return vector_type(*this) *= _s;
#else
#define expr(i) Base::values_[i] * _s
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise division by with scalar
inline vector_type operator/(const Scalar& _s) const {
#if DIM==N
return vector_type(*this) /= _s;
#else
#define expr(i) Base::values_[i] / _s
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
//---------------------------------------------------------- vector operators
/// component-wise self-multiplication
inline vector_type& operator*=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] *= _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// component-wise self-division
inline vector_type& operator/=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] /= _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// vector difference from this
inline vector_type& operator-=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] -= _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// vector self-addition
inline vector_type& operator+=(const vector_type& _rhs) {
#define expr(i) Base::values_[i] += _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// component-wise vector multiplication
inline vector_type operator*(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) *= _v;
#else
#define expr(i) Base::values_[i] * _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise vector division
inline vector_type operator/(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) /= _v;
#else
#define expr(i) Base::values_[i] / _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise vector addition
inline vector_type operator+(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) += _v;
#else
#define expr(i) Base::values_[i] + _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// component-wise vector difference
inline vector_type operator-(const vector_type& _v) const {
#if DIM==N
return vector_type(*this) -= _v;
#else
#define expr(i) Base::values_[i] - _v.Base::values_[i]
return vector_type(unroll_csv(expr));
#undef expr
#endif
}
/// unary minus
inline vector_type operator-(void) const {
vector_type v;
#define expr(i) v.Base::values_[i] = -Base::values_[i];
unroll(expr);
#undef expr
return v;
}
/// cross product: only defined for Vec3* as specialization
/// \see OpenMesh::cross
inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
#if DIM==3
{
return
VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
}
#else
;
#endif
/// compute scalar product
/// \see OpenMesh::dot
inline Scalar operator|(const vector_type& _rhs) const {
Scalar p(0);
#define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
unroll(expr);
#undef expr
return p;
}
//------------------------------------------------------------ euclidean norm
/// \name Euclidean norm calculations
//@{
/// compute euclidean norm
inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
inline Scalar length() const { return norm(); } // OpenSG interface
/// compute squared euclidean norm
inline Scalar sqrnorm() const
{
#if DIM==N
Scalar s(0);
#define expr(i) s += Base::values_[i] * Base::values_[i];
unroll(expr);
#undef expr
return s;
#else
#define expr(i) Base::values_[i]*Base::values_[i]
return (unroll_comb(expr, +));
#undef expr
#endif
}
/** normalize vector, return normalized vector
*/
inline vector_type& normalize()
{
*this /= norm();
return *this;
}
/** return normalized vector
*/
inline const vector_type normalized() const
{
return *this / norm();
}
/** normalize vector, return normalized vector and avoids div by zero
*/
inline vector_type& normalize_cond()
{
Scalar n = norm();
if (n != (Scalar)0.0)
{
*this /= n;
}
return *this;
}
//@}
//------------------------------------------------------------ euclidean norm
/// \name Non-Euclidean norm calculations
//@{
/// compute L1 (Manhattan) norm
inline Scalar l1_norm() const
{
#if DIM==N
Scalar s(0);
#define expr(i) s += std::abs(Base::values_[i]);
unroll(expr);
#undef expr
return s;
#else
#define expr(i) std::abs(Base::values_[i])
return (unroll_comb(expr, +));
#undef expr
#endif
}
/// compute l8_norm
inline Scalar l8_norm() const
{
return max_abs();
}
//@}
//------------------------------------------------------------ max, min, mean
/// \name Minimum maximum and mean
//@{
/// return the maximal component
inline Scalar max() const
{
Scalar m(Base::values_[0]);
for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
return m;
}
/// return the maximal absolute component
inline Scalar max_abs() const
{
Scalar m(std::abs(Base::values_[0]));
for(int i=1; i<DIM; ++i)
if(std::abs(Base::values_[i])>m)
m=std::abs(Base::values_[i]);
return m;
}
/// return the minimal component
inline Scalar min() const
{
Scalar m(Base::values_[0]);
for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
return m;
}
/// return the minimal absolute component
inline Scalar min_abs() const
{
Scalar m(std::abs(Base::values_[0]));
for(int i=1; i<DIM; ++i)
if(std::abs(Base::values_[i])<m)
m=std::abs(Base::values_[i]);
return m;
}
/// return arithmetic mean
inline Scalar mean() const {
Scalar m(Base::values_[0]);
for(int i=1; i<DIM; ++i) m+=Base::values_[i];
return m/Scalar(DIM);
}
/// return absolute arithmetic mean
inline Scalar mean_abs() const {
Scalar m(std::abs(Base::values_[0]));
for(int i=1; i<DIM; ++i) m+=std::abs(Base::values_[i]);
return m/Scalar(DIM);
}
/// minimize values: same as *this = min(*this, _rhs), but faster
inline vector_type& minimize(const vector_type& _rhs) {
#define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// minimize values and signalize coordinate minimization
inline bool minimized(const vector_type& _rhs) {
bool result(false);
#define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; }
unroll(expr);
#undef expr
return result;
}
/// maximize values: same as *this = max(*this, _rhs), but faster
inline vector_type& maximize(const vector_type& _rhs) {
#define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
unroll(expr);
#undef expr
return *this;
}
/// maximize values and signalize coordinate maximization
inline bool maximized(const vector_type& _rhs) {
bool result(false);
#define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; }
unroll(expr);
#undef expr
return result;
}
/// component-wise min
inline vector_type min(const vector_type& _rhs) const {
return vector_type(*this).minimize(_rhs);
}
/// component-wise max
inline vector_type max(const vector_type& _rhs) const {
return vector_type(*this).maximize(_rhs);
}
//@}
//------------------------------------------------------------ misc functions
/// component-wise apply function object with Scalar operator()(Scalar).
template<typename Functor>
inline vector_type apply(const Functor& _func) const {
vector_type result;
#define expr(i) result[i] = _func(Base::values_[i]);
unroll(expr);
#undef expr
return result;
}
/// store the same value in each component (e.g. to clear all entries)
vector_type& vectorize(const Scalar& _s) {
#define expr(i) Base::values_[i] = _s;
unroll(expr);
#undef expr
return *this;
}
/// store the same value in each component
static vector_type vectorized(const Scalar& _s) {
return vector_type().vectorize(_s);
}
/// lexicographical comparison
bool operator<(const vector_type& _rhs) const {
#define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
return (Base::values_[i] < _rhs.Base::values_[i]);
unroll(expr);
#undef expr
return false;
}
};
/// read the space-separated components of a vector from a stream
TEMPLATE_HEADER
inline std::istream&
operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
{
#define expr(i) is >> vec[i];
unroll(expr);
#undef expr
return is;
}
/// output a vector by printing its space-separated compontens
TEMPLATE_HEADER
inline std::ostream&
operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
{
#if DIM==N
for(int i=0; i<N-1; ++i) os << vec[i] << " ";
os << vec[N-1];
#else
#define expr(i) vec[i]
os << unroll_comb(expr, << " " <<);
#undef expr
#endif
return os;
}
// ----------------------------------------------------------------------------
#endif // included by VectorT.hh
//=============================================================================

View File

@ -0,0 +1,164 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_BINARY_HELPER_HH
#define OPENMESH_BINARY_HELPER_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
// -------------------- STL
#if defined( OM_CC_MIPS )
# include <stdio.h>
#else
# include <cstdio>
#endif
#include <iosfwd>
// -------------------- OpenMesh
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
/** \name Handling binary input/output.
These functions take care of swapping bytes to get the right Endian.
*/
//@{
//-----------------------------------------------------------------------------
/** Binary read a \c short from \c _is and perform byte swapping if
\c _swap is true */
short int read_short(FILE* _in, bool _swap=false);
/** Binary read an \c int from \c _is and perform byte swapping if
\c _swap is true */
int read_int(FILE* _in, bool _swap=false);
/** Binary read a \c float from \c _is and perform byte swapping if
\c _swap is true */
float read_float(FILE* _in, bool _swap=false);
/** Binary read a \c double from \c _is and perform byte swapping if
\c _swap is true */
double read_double(FILE* _in, bool _swap=false);
/** Binary read a \c short from \c _is and perform byte swapping if
\c _swap is true */
short int read_short(std::istream& _in, bool _swap=false);
/** Binary read an \c int from \c _is and perform byte swapping if
\c _swap is true */
int read_int(std::istream& _in, bool _swap=false);
/** Binary read a \c float from \c _is and perform byte swapping if
\c _swap is true */
float read_float(std::istream& _in, bool _swap=false);
/** Binary read a \c double from \c _is and perform byte swapping if
\c _swap is true */
double read_double(std::istream& _in, bool _swap=false);
/** Binary write a \c short to \c _os and perform byte swapping if
\c _swap is true */
void write_short(short int _i, FILE* _out, bool _swap=false);
/** Binary write an \c int to \c _os and perform byte swapping if
\c _swap is true */
void write_int(int _i, FILE* _out, bool _swap=false);
/** Binary write a \c float to \c _os and perform byte swapping if
\c _swap is true */
void write_float(float _f, FILE* _out, bool _swap=false);
/** Binary write a \c double to \c _os and perform byte swapping if
\c _swap is true */
void write_double(double _d, FILE* _out, bool _swap=false);
/** Binary write a \c short to \c _os and perform byte swapping if
\c _swap is true */
void write_short(short int _i, std::ostream& _out, bool _swap=false);
/** Binary write an \c int to \c _os and perform byte swapping if
\c _swap is true */
void write_int(int _i, std::ostream& _out, bool _swap=false);
/** Binary write a \c float to \c _os and perform byte swapping if
\c _swap is true */
void write_float(float _f, std::ostream& _out, bool _swap=false);
/** Binary write a \c double to \c _os and perform byte swapping if
\c _swap is true */
void write_double(double _d, std::ostream& _out, bool _swap=false);
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_MESHREADER_HH defined
//=============================================================================

View File

@ -0,0 +1,115 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper file for static builds
//
// In opposite to dynamic builds where the instance of every reader module
// is generated within the OpenMesh library, static builds only instanciate
// objects that are at least referenced once. As all reader modules are
// never used directly, they will not be part of a static build, hence
// this file.
//
//=============================================================================
#ifndef __IOINSTANCES_HH__
#define __IOINSTANCES_HH__
#if defined(OM_STATIC_BUILD) || defined(ARCH_DARWIN)
//=============================================================================
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
#include <OpenMesh/Core/IO/reader/OBJReader.hh>
#include <OpenMesh/Core/IO/reader/OFFReader.hh>
#include <OpenMesh/Core/IO/reader/PLYReader.hh>
#include <OpenMesh/Core/IO/reader/STLReader.hh>
#include <OpenMesh/Core/IO/reader/OMReader.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
#include <OpenMesh/Core/IO/writer/OBJWriter.hh>
#include <OpenMesh/Core/IO/writer/OFFWriter.hh>
#include <OpenMesh/Core/IO/writer/STLWriter.hh>
#include <OpenMesh/Core/IO/writer/OMWriter.hh>
#include <OpenMesh/Core/IO/writer/PLYWriter.hh>
//=== NAMESPACES ==============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
// Instanciate every Reader module
static BaseReader* OFFReaderInstance = &OFFReader();
static BaseReader* OBJReaderInstance = &OBJReader();
static BaseReader* PLYReaderInstance = &PLYReader();
static BaseReader* STLReaderInstance = &STLReader();
static BaseReader* OMReaderInstance = &OMReader();
// Instanciate every writer module
static BaseWriter* OBJWriterInstance = &OBJWriter();
static BaseWriter* OFFWriterInstance = &OFFWriter();
static BaseWriter* STLWriterInstance = &STLWriter();
static BaseWriter* OMWriterInstance = &OMWriter();
static BaseWriter* PLYWriterInstance = &PLYWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // static ?
#endif //__IOINSTANCES_HH__
//=============================================================================

View File

@ -0,0 +1,272 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements the OpenMesh IOManager singleton
//
//=============================================================================
#ifndef __IOMANAGER_HH__
#define __IOMANAGER_HH__
//=== INCLUDES ================================================================
// STL
#include <iosfwd>
#include <sstream>
#include <string>
#include <set>
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/IO/Options.hh>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
#include <OpenMesh/Core/IO/importer/BaseImporter.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
#include <OpenMesh/Core/Utils/SingletonT.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/** This is the real IOManager class that is later encapsulated by
SingletonT to enforce its uniqueness. _IOManager_ is not meant to be used
directly by the programmer - the IOManager alias exists for this task.
All reader/writer modules register themselves at this class. For
reading or writing data all modules are asked to do the job. If no
suitable module is found, an error is returned.
For the sake of reading, the target data structure is hidden
behind the BaseImporter interface that takes care of adding
vertices or faces.
Writing from a source structure is encapsulate similarly behind a
BaseExporter interface, providing iterators over vertices/faces to
the writer modules.
\see \ref mesh_io
*/
class OPENMESHDLLEXPORT _IOManager_
{
private:
/// Constructor has nothing todo for the Manager
_IOManager_() {}
/// Destructor has nothing todo for the Manager
~_IOManager_() {};
/** Declare the singleton getter function as friend to access the private constructor
and destructor
*/
friend OPENMESHDLLEXPORT _IOManager_& IOManager();
public:
/**
Read a mesh from file _filename. The target data structure is specified
by the given BaseImporter. The \c read method consecutively queries all
of its reader modules. True is returned upon success, false if all
reader modules failed to interprete _filename.
*/
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt);
/**
Read a mesh from open std::istream _is. The target data structure is specified
by the given BaseImporter. The \c sread method consecutively queries all
of its reader modules. True is returned upon success, false if all
reader modules failed to use _is.
*/
bool read(std::istream& _filename,
const std::string& _ext,
BaseImporter& _bi,
Options& _opt);
/** Write a mesh to file _filename. The source data structure is specified
by the given BaseExporter. The \c save method consecutively queries all
of its writer modules. True is returned upon success, false if all
writer modules failed to write the requested format.
Options is determined by _filename's extension.
*/
bool write(const std::string& _filename,
BaseExporter& _be,
Options _opt=Options::Default,
std::streamsize _precision = 6);
/** Write a mesh to open std::ostream _os. The source data structure is specified
by the given BaseExporter. The \c save method consecutively queries all
of its writer modules. True is returned upon success, false if all
writer modules failed to write the requested format.
Options is determined by _filename's extension.
*/
bool write(std::ostream& _filename,
const std::string& _ext,
BaseExporter& _be,
Options _opt=Options::Default,
std::streamsize _precision = 6);
/// Returns true if the format is supported by one of the reader modules.
bool can_read( const std::string& _format ) const;
/// Returns true if the format is supported by one of the writer modules.
bool can_write( const std::string& _format ) const;
size_t binary_size(const std::string& _format,
BaseExporter& _be,
Options _opt = Options::Default)
{
const BaseWriter *bw = find_writer(_format);
return bw ? bw->binary_size(_be,_opt) : 0;
}
public: //-- QT convenience function ------------------------------------------
/** Returns all readable file extension + descriptions in one string.
File formats are separated by <c>;;</c>.
Convenience function for Qt file dialogs.
*/
const std::string& qt_read_filters() const { return read_filters_; }
/** Returns all writeable file extension + descriptions in one string.
File formats are separated by <c>;;</c>.
Convenience function for Qt file dialogs.
*/
const std::string& qt_write_filters() const { return write_filters_; }
private:
// collect all readable file extensions
void update_read_filters();
// collect all writeable file extensions
void update_write_filters();
public: //-- SYSTEM PART------------------------------------------------------
/** Registers a new reader module. A call to this function should be
implemented in the constructor of all classes derived from BaseReader.
*/
bool register_module(BaseReader* _bl)
{
reader_modules_.insert(_bl);
update_read_filters();
return true;
}
/** Registers a new writer module. A call to this function should be
implemented in the constructor of all classed derived from BaseWriter.
*/
bool register_module(BaseWriter* _bw)
{
writer_modules_.insert(_bw);
update_write_filters();
return true;
}
private:
const BaseWriter *find_writer(const std::string& _format);
// stores registered reader modules
std::set<BaseReader*> reader_modules_;
// stores registered writer modules
std::set<BaseWriter*> writer_modules_;
// input filters (e.g. for Qt file dialog)
std::string read_filters_;
// output filters (e.g. for Qt file dialog)
std::string write_filters_;
};
//=============================================================================
//_IOManager_* __IOManager_instance; Causes memory leak, as destructor is never called
OPENMESHDLLEXPORT _IOManager_& IOManager();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,296 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef OM_MESHIO_HH
#define OM_MESHIO_HH
//=== INCLUDES ================================================================
// -------------------- system settings
#include <OpenMesh/Core/System/config.h>
// -------------------- check include order
#if defined (OPENMESH_TRIMESH_ARRAY_KERNEL_HH) || \
defined (OPENMESH_POLYMESH_ARRAY_KERNEL_HH)
// Issue warning if MeshIO was not included before Mesh Type
// Nobody knows why this order was enforced.
// If somebody encounters an error resulting from a wrong order, please report it to the OpenMesh developers.
// If we don't here about any errors, this check will be removed
// @TODO: Remove after reasonable time
#ifdef WIN32
#pragma message("MeshIO.hh was included after Mesh Type. You may ignore this warning. Please report errors resulting ifrom this order to the developers!")
#else
#warning "MeshIO.hh was included after Mesh Type. You may ignore this warning. Please report errors resulting from this order to the developers!"
#endif
#endif
// -------------------- OpenMesh
#include <OpenMesh/Core/IO/SR_store.hh>
#include <OpenMesh/Core/IO/IOManager.hh>
#include <OpenMesh/Core/IO/importer/ImporterT.hh>
#include <OpenMesh/Core/IO/exporter/ExporterT.hh>
//== NAMESPACES ==============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/** \name Mesh Reading / Writing
Convenience functions the map to IOManager functions.
\see OpenMesh::IO::_IOManager_
*/
//@{
//-----------------------------------------------------------------------------
/** \brief Read a mesh from file _filename.
The file format is determined by the file extension.
\note If you link statically against OpenMesh, you have to add
the define OM_STATIC_BUILD to your application. This will
ensure that readers and writers get initialized correctly.
@param _mesh The target mesh that will be filled with the read data
@param _filename fill to load
@return Successful?
*/
template <class Mesh>
bool
read_mesh(Mesh& _mesh,
const std::string& _filename)
{
Options opt;
return read_mesh(_mesh, _filename, opt, true);
}
/** \brief Read a mesh from file _filename.
The file format is determined by the file extension.
\note If you link statically against OpenMesh, you have to add
the define OM_STATIC_BUILD to your application. This will
ensure that readers and writers get initialized correctly.
@param _mesh The target mesh that will be filled with the read data
@param _filename fill to load
@param _opt Reader options (e.g. skip loading of normals ... depends
on the reader capabilities). Note that simply passing an
Options::Flag enum is not sufficient.
@param _clear Clear the target data before filling it (allows to
load multiple files into one Mesh). If you only want to read a mesh
without clearing set _clear to false. Providing a default Options
object is sufficient in this case.
@return Successful?
*/
template <class Mesh>
bool
read_mesh(Mesh& _mesh,
const std::string& _filename,
Options& _opt,
bool _clear = true)
{
if (_clear) _mesh.clear();
ImporterT<Mesh> importer(_mesh);
return IOManager().read(_filename, importer, _opt);
}
/** \brief Read a mesh from file open std::istream.
The file format is determined by parameter _ext. _ext has to include
".[format]" in order to work properly (e.g. ".OFF")
\note If you link statically against OpenMesh, you have to add
the define OM_STATIC_BUILD to your application. This will
ensure that readers and writers get initialized correctly.
@param _mesh The target mesh that will be filled with the read data
@param _is stream to load the data from
@param _ext The file format that is written to the stream
@param _opt Reader options (e.g. skip loading of normals ... depends
on the reader capabilities)
@param _clear Clear the target data before filling it (allows to
load multiple files into one Mesh)
@return Successful?
*/
template <class Mesh>
bool
read_mesh(Mesh& _mesh,
std::istream& _is,
const std::string& _ext,
Options& _opt,
bool _clear = true)
{
if (_clear) _mesh.clear();
ImporterT<Mesh> importer(_mesh);
return IOManager().read(_is,_ext, importer, _opt);
}
//-----------------------------------------------------------------------------
/** \brief Write a mesh to the file _filename.
The file format is determined by _filename's extension.
\note If you link statically against OpenMesh, you have to add
the define OM_STATIC_BUILD to your application. This will
ensure that readers and writers get initialized correctly.
@param _mesh The mesh that will be written to file
@param _filename output filename
@param _opt Writer options (e.g. writing of normals ... depends
on the writer capabilities)
@param _precision specifies stream precision for ascii files
@return Successful?
*/
template <class Mesh>
bool write_mesh(const Mesh& _mesh,
const std::string& _filename,
Options _opt = Options::Default,
std::streamsize _precision = 6)
{
ExporterT<Mesh> exporter(_mesh);
return IOManager().write(_filename, exporter, _opt, _precision);
}
//-----------------------------------------------------------------------------
/** Write a mesh to an open std::ostream.
The file format is determined by parameter _ext. _ext has to include
".[format]" in order to work properly (e.g. ".OFF")
\note If you link statically against OpenMesh, you have to add
the define OM_STATIC_BUILD to your application. This will
ensure that readers and writers get initialized correctly.
@param _mesh The mesh that will be written to file
@param _os output stream to write into
@param _ext extension defining the type of output
@param _opt Writer options (e.g. writing of normals ... depends
on the writer capabilities)
@param _precision specifies stream precision for ascii files
@return Successful?
*/
template <class Mesh>
bool write_mesh(const Mesh& _mesh,
std::ostream& _os,
const std::string& _ext,
Options _opt = Options::Default,
std::streamsize _precision = 6)
{
ExporterT<Mesh> exporter(_mesh);
return IOManager().write(_os,_ext, exporter, _opt, _precision);
}
//-----------------------------------------------------------------------------
/** \brief Get binary size of data
This function calls the corresponding writer which calculates the size
of the data that would be written to a binary file
The file format is determined by parameter _ext. _ext has to include
".[format]" in order to work properly (e.g. ".OFF")
@param _mesh Mesh to write
@param _ext extension of the file (used to determine the writing module)
@param _opt Writer options (e.g. writing of normals ... depends
on the writer capabilities)
@return Binary size in bytes used when writing the data
*/
template <class Mesh>
size_t binary_size(const Mesh& _mesh,
const std::string& _ext,
Options _opt = Options::Default)
{
ExporterT<Mesh> exporter(_mesh);
return IOManager().binary_size(_ext, exporter, _opt);
}
//-----------------------------------------------------------------------------
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#if defined(OM_STATIC_BUILD) || defined(ARCH_DARWIN)
# include <OpenMesh/Core/IO/IOInstances.hh>
#endif
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,99 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef OPENMESH_IO_OFFFORMAT_HH
#define OPENMESH_IO_OFFFORMAT_HH
//=== INCLUDES ================================================================
// OpenMesh
#include <OpenMesh/Core/System/config.h>
//== NAMESPACES ==============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/** \name Mesh Reading / Writing
Option for writer modules.
*/
//@{
//-----------------------------------------------------------------------------
#ifndef DOXY_IGNORE_THIS
struct OPENMESHDLLEXPORT OFFFormat
{
typedef int integer_type;
typedef float float_type;
};
#endif
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,751 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef OPENMESH_IO_OMFORMAT_HH
#define OPENMESH_IO_OMFORMAT_HH
//=== INCLUDES ================================================================
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/System/omstream.hh>
#include <OpenMesh/Core/IO/SR_store.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <OpenMesh/Core/Utils/Endian.hh>
#include <OpenMesh/Core/Utils/vector_traits.hh>
// --------------------
#include <iostream>
#if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000)
# include <OpenMesh/Tools/Utils/NumLimitsT.hh>
# define OM_MISSING_HEADER_LIMITS 1
#else
# include <limits>
#endif
//== NAMESPACES ==============================================================
#ifndef DOXY_IGNORE_THIS
namespace OpenMesh {
namespace IO {
namespace OMFormat {
//=== IMPLEMENTATION ==========================================================
/** \name Mesh Reading / Writing
*/
//@{
//-----------------------------------------------------------------------------
// <:Header>
// <:Comment>
// Chunk 0
// <:ChunkHeader>
// <:Comment>
// data
// Chunk 1
// <:ChunkHeader>
// <:Comment>
// data
// .
// .
// .
// Chunk N
//
// NOTICE!
//
// The usage of data types who differ in size
// on different pc architectures (32/64 bit) and/or
// operating systems, e.g. (unsigned) long, size_t,
// is not recommended because of inconsistencies
// in case of cross writing and reading.
//
// Basic types that are supported are:
typedef unsigned char uchar;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef float32_t float32;
typedef float64_t float64;
struct Header
{
uchar magic_[2]; // OM
uchar mesh_; // [T]riangles, [Q]uads, [P]olygonals
uint8 version_;
uint32 n_vertices_;
uint32 n_faces_;
uint32 n_edges_;
size_t store( std::ostream& _os, bool _swap ) const
{
_os.write( (char*)this, 4); // magic_, mesh_, version_
size_t bytes = 4;
bytes += binary<uint32_t>::store( _os, n_vertices_, _swap );
bytes += binary<uint32_t>::store( _os, n_faces_, _swap );
bytes += binary<uint32_t>::store( _os, n_edges_, _swap );
return bytes;
}
size_t restore( std::istream& _is, bool _swap )
{
if (_is.read( (char*)this, 4 ).eof())
return 0;
size_t bytes = 4;
bytes += binary<uint32_t>::restore( _is, n_vertices_, _swap );
bytes += binary<uint32_t>::restore( _is, n_faces_, _swap );
bytes += binary<uint32_t>::restore( _is, n_edges_, _swap );
return bytes;
}
};
struct Chunk
{
// Hardcoded this size to an uint32 to make the system 32/64 bit compatible.
// Needs further investigation!
typedef uint32 esize_t; // element size, used for custom properties
enum Type {
Type_Pos = 0x00,
Type_Normal = 0x01,
Type_Texcoord = 0x02,
Type_Status = 0x03,
Type_Color = 0x04,
Type_Custom = 0x06,
Type_Topology = 0x07
};
enum Entity {
Entity_Vertex = 0x00,
Entity_Mesh = 0x01,
Entity_Face = 0x02,
Entity_Edge = 0x04,
Entity_Halfedge = 0x06,
Entity_Sentinel = 0x07
};
enum Dim {
Dim_1D = 0x00,
Dim_2D = 0x01,
Dim_3D = 0x02,
Dim_4D = 0x03,
Dim_5D = 0x04,
Dim_6D = 0x05,
Dim_7D = 0x06,
Dim_8D = 0x07
};
enum Integer_Size {
Integer_8 = 0x00, // 1 byte for (unsigned) char
Integer_16 = 0x01, // 2 bytes for short
Integer_32 = 0x02, // 4 bytes for long
Integer_64 = 0x03 // 8 bytes for long long
};
enum Float_Size {
Float_32 = 0x00, // 4 bytes for float
Float_64 = 0x01, // 8 bytes for double
Float_128 = 0x02 // 16 bytes for long double (an assumption!)
};
static const int SIZE_RESERVED = 1; // 1
static const int SIZE_NAME = 1; // 2
static const int SIZE_ENTITY = 3; // 5
static const int SIZE_TYPE = 4; // 9
static const int SIZE_SIGNED = 1; // 10
static const int SIZE_FLOAT = 1; // 11
static const int SIZE_DIM = 3; // 14
static const int SIZE_BITS = 2; // 16
static const int OFF_RESERVED = 0; // 0
static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED; // 2
static const int OFF_ENTITY = SIZE_NAME + OFF_NAME; // 3
static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY; // 5
static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE; // 9
static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED; // 10
static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT; // 11
static const int OFF_BITS = SIZE_DIM + OFF_DIM; // 14
// !Attention! When changing the bit size, the operators
// << (uint16, Header) and << (Header, uint16) must be changed as well
//
// Entries signed_, float_, dim_, bits_ are not used when type_
// equals Type_Custom
//
struct Header // 16 bits long
{
unsigned reserved_: SIZE_RESERVED;
unsigned name_ : SIZE_NAME; // 1 named property, 0 anonymous
unsigned entity_ : SIZE_ENTITY; // 0 vertex, 1 mesh, 2 edge,
// 4 halfedge, 6 face
unsigned type_ : SIZE_TYPE; // 0 pos, 1 normal, 2 texcoord,
// 3 status, 4 color 6 custom 7 topology
unsigned signed_ : SIZE_SIGNED; // bool
unsigned float_ : SIZE_FLOAT; // bool
unsigned dim_ : SIZE_DIM; // 0 1D, 1 2D, 2 3D, .., 7 8D
unsigned bits_ : SIZE_BITS; // {8, 16, 32, 64} | {32, 64, 128}
// (integer) (float)
unsigned unused_ : 16; // fill up to 32 bits
}; // struct Header
class PropertyName : public std::string
{
public:
static const size_t size_max = 256;
PropertyName( ) { }
PropertyName( const std::string& _name ) { *this = _name; }
bool is_valid() const { return is_valid( size() ); }
static bool is_valid( size_t _s ) { return _s <= size_max; }
PropertyName& operator = ( const std::string& _rhs )
{
assert( is_valid( _rhs.size() ) );
if ( is_valid( _rhs.size() ) )
std::string::operator = ( _rhs );
else
{
omerr() << "Warning! Property name too long. Will be shortened!\n";
this->std::string::operator = ( _rhs.substr(0, size_max) );
}
return *this;
}
};
}; // Chunk
// ------------------------------------------------------------ Helper
// -------------------- get size information
/// Return size of header in bytes.
inline size_t header_size(void) { return sizeof(Header); }
/// Return size of chunk header in bytes.
inline size_t chunk_header_size( void ) { return sizeof(uint16); }
/// Return the size of a scale in bytes.
inline size_t scalar_size( const Chunk::Header& _hdr )
{
return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_);
}
/// Return the dimension of the vector in a chunk
inline size_t dimensions(const Chunk::Header& _chdr) { return _chdr.dim_+1; }
/// Return the size of a vector in bytes.
inline size_t vector_size( const Chunk::Header& _chdr )
{
return dimensions(_chdr)*scalar_size(_chdr);
}
/// Return the size of chunk data in bytes
inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr )
{
size_t C;
switch( _chunk_hdr.entity_ )
{
case Chunk::Entity_Vertex: C = _hdr.n_vertices_; break;
case Chunk::Entity_Face: C = _hdr.n_faces_; break;
case Chunk::Entity_Halfedge: C = _hdr.n_edges_*2; break;
case Chunk::Entity_Edge: C = _hdr.n_edges_; break;
case Chunk::Entity_Mesh: C = 1; break;
default:
C = 0;
std::cerr << "Invalid value in _chunk_hdr.entity_\n";
assert( false );
break;
}
return C * vector_size( _chunk_hdr );
}
inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr )
{
return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr );
}
// -------------------- convert from Chunk::Header to storage type
uint16& operator << (uint16& val, const Chunk::Header& hdr);
Chunk::Header& operator << (Chunk::Header& hdr, const uint16 val);
// -------------------- type information
template <typename T> bool is_float(const T&)
{
#if defined(OM_MISSING_HEADER_LIMITS)
return !Utils::NumLimitsT<T>::is_integer();
#else
return !std::numeric_limits<T>::is_integer;
#endif
}
template <typename T> bool is_integer(const T)
{
#if defined(OM_MISSING_HEADER_LIMITS)
return Utils::NumLimitsT<T>::is_integer();
#else
return std::numeric_limits<T>::is_integer;
#endif
}
template <typename T> bool is_signed(const T&)
{
#if defined(OM_MISSING_HEADER_LIMITS)
return Utils::NumLimitsT<T>::is_signed();
#else
return std::numeric_limits<T>::is_signed;
#endif
}
// -------------------- conversions (format type <- type/value)
template <typename VecType>
inline
Chunk::Dim dim( VecType )
{
assert( vector_traits< VecType >::size() < 9 );
return static_cast<Chunk::Dim>(vector_traits< VecType >::size() - 1);
}
template <typename VecType>
inline
Chunk::Dim dim( const Chunk::Header& _hdr )
{
return static_cast<Chunk::Dim>( _hdr.dim_ );
}
// calc minimum (power-of-2) number of bits needed
Chunk::Integer_Size needed_bits( size_t s );
// Convert size of type to Integer_Size
#ifdef NDEBUG
template <typename T> Chunk::Integer_Size integer_size(const T&)
#else
template <typename T> Chunk::Integer_Size integer_size(const T& d)
#endif
{
#ifndef NDEBUG
assert( is_integer(d) );
#endif
switch( sizeof(T) )
{
case 1: return OMFormat::Chunk::Integer_8;
case 2: return OMFormat::Chunk::Integer_16;
case 4: return OMFormat::Chunk::Integer_32;
case 8: return OMFormat::Chunk::Integer_64;
default:
std::cerr << "Invalid value in integer_size\n";
assert( false );
break;
}
return Chunk::Integer_Size(0);
}
// Convert size of type to FLoat_Size
#ifdef NDEBUG
template <typename T> Chunk::Float_Size float_size(const T&)
#else
template <typename T> Chunk::Float_Size float_size(const T& d)
#endif
{
#ifndef NDEBUG
assert( is_float(d) );
#endif
switch( sizeof(T) )
{
case 4: return OMFormat::Chunk::Float_32;
case 8: return OMFormat::Chunk::Float_64;
case 16: return OMFormat::Chunk::Float_128;
default:
std::cerr << "Invalid value in float_size\n";
assert( false );
break;
}
return Chunk::Float_Size(0);
}
// Return the storage type (Chunk::Header::bits_)
template <typename T>
inline
unsigned int bits(const T& val)
{
return is_integer(val)
? (static_cast<unsigned int>(integer_size(val)))
: (static_cast<unsigned int>(float_size(val)));
}
// -------------------- create/read version
inline uint8 mk_version(const uint16 major, const uint16 minor)
{ return (major & 0x07) << 5 | (minor & 0x1f); }
inline uint16 major_version(const uint8 version)
{ return (version >> 5) & 0x07; }
inline uint16 minor_version(const uint8 version)
{ return (version & 0x001f); }
// ---------------------------------------- convenience functions
const char *as_string(Chunk::Type t);
const char *as_string(Chunk::Entity e);
const char *as_string(Chunk::Dim d);
const char *as_string(Chunk::Integer_Size d);
const char *as_string(Chunk::Float_Size d);
std::ostream& operator << ( std::ostream& _os, const Header& _h );
std::ostream& operator << ( std::ostream& _os, const Chunk::Header& _c );
//@}
} // namespace OMFormat
// -------------------- (re-)store header
template <> inline
size_t store( std::ostream& _os, const OMFormat::Header& _hdr, bool _swap)
{ return _hdr.store( _os, _swap ); }
template <> inline
size_t restore( std::istream& _is, OMFormat::Header& _hdr, bool _swap )
{ return _hdr.restore( _is, _swap ); }
// -------------------- (re-)store chunk header
template <> inline
size_t
store( std::ostream& _os, const OMFormat::Chunk::Header& _hdr, bool _swap)
{
OMFormat::uint16 val; val << _hdr;
return binary<uint16_t>::store( _os, val, _swap );
}
template <> inline
size_t
restore( std::istream& _is, OMFormat::Chunk::Header& _hdr, bool _swap )
{
OMFormat::uint16 val;
size_t bytes = binary<uint16_t>::restore( _is, val, _swap );
_hdr << val;
return bytes;
}
// -------------------- (re-)store integer with wanted number of bits (bytes)
typedef GenProg::TrueType t_signed;
typedef GenProg::FalseType t_unsigned;
// helper to store a an integer
template< typename T >
size_t
store( std::ostream& _os,
const T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_signed);
// helper to store a an unsigned integer
template< typename T >
size_t
store( std::ostream& _os,
const T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_unsigned);
/// Store an integer with a wanted number of bits
template< typename T >
inline
size_t
store( std::ostream& _os,
const T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap)
{
assert( OMFormat::is_integer( _val ) );
if ( OMFormat::is_signed( _val ) )
return store( _os, _val, _b, _swap, t_signed() );
return store( _os, _val, _b, _swap, t_unsigned() );
}
// helper to store a an integer
template< typename T > inline
size_t restore( std::istream& _is,
T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_signed);
// helper to store a an unsigned integer
template< typename T > inline
size_t restore( std::istream& _is,
T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_unsigned);
/// Restore an integer with a wanted number of bits
template< typename T >
inline
size_t
restore( std::istream& _is,
T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap)
{
assert( OMFormat::is_integer( _val ) );
if ( OMFormat::is_signed( _val ) )
return restore( _is, _val, _b, _swap, t_signed() );
return restore( _is, _val, _b, _swap, t_unsigned() );
}
//
// ---------------------------------------- storing vectors
template <typename VecT> inline
size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<2>,
bool _swap )
{
size_t bytes = store( _os, _vec[0], _swap );
bytes += store( _os, _vec[1], _swap );
return bytes;
}
template <typename VecT> inline
size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<3>,
bool _swap )
{
size_t bytes = store( _os, _vec[0], _swap );
bytes += store( _os, _vec[1], _swap );
bytes += store( _os, _vec[2], _swap );
return bytes;
}
template <typename VecT> inline
size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<4>,
bool _swap )
{
size_t bytes = store( _os, _vec[0], _swap );
bytes += store( _os, _vec[1], _swap );
bytes += store( _os, _vec[2], _swap );
bytes += store( _os, _vec[3], _swap );
return bytes;
}
template <typename VecT> inline
size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<1>,
bool _swap )
{
return store( _os, _vec[0], _swap );
}
/// storing a vector type
template <typename VecT> inline
size_t vector_store( std::ostream& _os, const VecT& _vec, bool _swap )
{
return store( _os, _vec,
GenProg::Int2Type< vector_traits<VecT>::size_ >(),
_swap );
}
// ---------------------------------------- restoring vectors
template <typename VecT>
inline
size_t
restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<2>,
bool _swap )
{
size_t bytes = restore( _is, _vec[0], _swap );
bytes += restore( _is, _vec[1], _swap );
return bytes;
}
template <typename VecT>
inline
size_t
restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<3>,
bool _swap )
{
typedef typename vector_traits<VecT>::value_type scalar_type;
size_t bytes;
bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
return bytes;
}
template <typename VecT>
inline
size_t
restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<4>,
bool _swap )
{
typedef typename vector_traits<VecT>::value_type scalar_type;
size_t bytes;
bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
bytes += binary<scalar_type>::restore( _is, _vec[3], _swap );
return bytes;
}
template <typename VecT>
inline
size_t
restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<1>,
bool _swap )
{
return restore( _is, _vec[0], _swap );
}
/// Restoring a vector type
template <typename VecT>
inline
size_t
vector_restore( std::istream& _is, VecT& _vec, bool _swap )
{
return restore( _is, _vec,
GenProg::Int2Type< vector_traits<VecT>::size_ >(),
_swap );
}
// ---------------------------------------- storing property names
template <>
inline
size_t store( std::ostream& _os, const OMFormat::Chunk::PropertyName& _pn,
bool _swap )
{
store( _os, _pn.size(), OMFormat::Chunk::Integer_8, _swap ); // 1 byte
if ( _pn.size() )
_os.write( _pn.c_str(), _pn.size() ); // size bytes
return _pn.size() + 1;
}
template <>
inline
size_t restore( std::istream& _is, OMFormat::Chunk::PropertyName& _pn,
bool _swap )
{
size_t size;
restore( _is, size, OMFormat::Chunk::Integer_8, _swap); // 1 byte
assert( OMFormat::Chunk::PropertyName::is_valid( size ) );
if ( size > 0 )
{
char buf[256];
_is.read( buf, size ); // size bytes
buf[size] = '\0';
_pn.resize(size);
_pn = buf;
}
return size+1;
}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
#endif
//=============================================================================
#if defined(OM_MISSING_HEADER_LIMITS)
# undef OM_MISSING_HEADER_LIMITS
#endif
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC)
# define OPENMESH_IO_OMFORMAT_TEMPLATES
# include "OMFormatT.cc"
#endif
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,245 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#define OPENMESH_IO_OMFORMAT_CC
//== INCLUDES =================================================================
#include <OpenMesh/Core/IO/OMFormat.hh>
#include <algorithm>
#include <iomanip>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
// helper to store a an integer
template< typename T >
size_t
store( std::ostream& _os,
const T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_signed)
{
assert( OMFormat::is_integer( _val ) );
switch( _b )
{
case OMFormat::Chunk::Integer_8:
{
OMFormat::int8 v = static_cast<OMFormat::int8>(_val);
return store( _os, v, _swap );
}
case OMFormat::Chunk::Integer_16:
{
OMFormat::int16 v = static_cast<OMFormat::int16>(_val);
return store( _os, v, _swap );
}
case OMFormat::Chunk::Integer_32:
{
OMFormat::int32 v = static_cast<OMFormat::int32>(_val);
return store( _os, v, _swap );
}
case OMFormat::Chunk::Integer_64:
{
OMFormat::int64 v = static_cast<OMFormat::int64>(_val);
return store( _os, v, _swap );
}
}
return 0;
}
// helper to store a an unsigned integer
template< typename T >
size_t
store( std::ostream& _os,
const T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_unsigned)
{
assert( OMFormat::is_integer( _val ) );
switch( _b )
{
case OMFormat::Chunk::Integer_8:
{
OMFormat::uint8 v = static_cast<OMFormat::uint8>(_val);
return store( _os, v, _swap );
}
case OMFormat::Chunk::Integer_16:
{
OMFormat::uint16 v = static_cast<OMFormat::uint16>(_val);
return store( _os, v, _swap );
}
case OMFormat::Chunk::Integer_32:
{
OMFormat::uint32 v = static_cast<OMFormat::uint32>(_val);
return store( _os, v, _swap );
}
case OMFormat::Chunk::Integer_64:
{
OMFormat::uint64 v = static_cast<OMFormat::uint64>(_val);
return store( _os, v, _swap );
}
}
return 0;
}
// helper to restore a an integer
template< typename T >
size_t
restore( std::istream& _is,
T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_signed)
{
assert( OMFormat::is_integer( _val ) );
size_t bytes = 0;
switch( _b )
{
case OMFormat::Chunk::Integer_8:
{
OMFormat::int8 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
case OMFormat::Chunk::Integer_16:
{
OMFormat::int16 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
case OMFormat::Chunk::Integer_32:
{
OMFormat::int32 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
case OMFormat::Chunk::Integer_64:
{
OMFormat::int64 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
}
return bytes;
}
// helper to restore a an unsigned integer
template< typename T >
size_t
restore( std::istream& _is,
T& _val,
OMFormat::Chunk::Integer_Size _b,
bool _swap,
t_unsigned)
{
assert( OMFormat::is_integer( _val ) );
size_t bytes = 0;
switch( _b )
{
case OMFormat::Chunk::Integer_8:
{
OMFormat::uint8 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
case OMFormat::Chunk::Integer_16:
{
OMFormat::uint16 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
case OMFormat::Chunk::Integer_32:
{
OMFormat::uint32 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
case OMFormat::Chunk::Integer_64:
{
OMFormat::uint64 v;
bytes = restore( _is, v, _swap );
_val = static_cast<T>(v);
break;
}
}
return bytes;
}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================

View File

@ -0,0 +1,250 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef OPENMESH_IO_OPTIONS_HH
#define OPENMESH_IO_OPTIONS_HH
//=== INCLUDES ================================================================
// OpenMesh
#include <OpenMesh/Core/System/config.h>
//== NAMESPACES ==============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/** \name Mesh Reading / Writing
Option for reader and writer modules.
*/
//@{
//-----------------------------------------------------------------------------
/** \brief Set options for reader/writer modules.
*
* The class is used in a twofold way.
* -# In combination with reader modules the class is used
* - to pass hints to the reading module, whether the input is
* binary and what byte ordering the binary data has
* - to retrieve information about the file contents after
* succesful reading.
* -# In combination with write modules the class gives directions to
* the writer module, whether to
* - use binary mode or not and what byte order to use
* - store one of the standard properties.
*
* The option are defined in \c Options::Flag as bit values and stored in
* an \c int value as a bitset.
*/
class Options
{
public:
typedef int enum_type;
typedef enum_type value_type;
/// Definitions of %Options for reading and writing. The options can be
/// or'ed.
enum Flag {
Default = 0x0000, ///< No options
Binary = 0x0001, ///< Set binary mode for r/w
MSB = 0x0002, ///< Assume big endian byte ordering
LSB = 0x0004, ///< Assume little endian byte ordering
Swap = 0x0008, ///< Swap byte order in binary mode
VertexNormal = 0x0010, ///< Has (r) / store (w) vertex normals
VertexColor = 0x0020, ///< Has (r) / store (w) vertex colors
VertexTexCoord = 0x0040, ///< Has (r) / store (w) texture coordinates
EdgeColor = 0x0080, ///< Has (r) / store (w) edge colors
FaceNormal = 0x0100, ///< Has (r) / store (w) face normals
FaceColor = 0x0200, ///< Has (r) / store (w) face colors
FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates
ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors
ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files)
Custom = 0x2000 ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version)
};
public:
/// Default constructor
Options() : flags_( Default )
{ }
/// Copy constructor
Options(const Options& _opt) : flags_(_opt.flags_)
{ }
/// Initializing constructor setting a single option
Options(Flag _flg) : flags_( _flg)
{ }
/// Initializing constructor setting multiple options
Options(const value_type _flgs) : flags_( _flgs)
{ }
~Options()
{ }
/// Restore state after default constructor.
void cleanup(void)
{ flags_ = Default; }
/// Clear all bits.
void clear(void)
{ flags_ = 0; }
/// Returns true if all bits are zero.
bool is_empty(void) const { return !flags_; }
public:
//@{
/// Copy options defined in _rhs.
Options& operator = ( const Options& _rhs )
{ flags_ = _rhs.flags_; return *this; }
Options& operator = ( const value_type _rhs )
{ flags_ = _rhs; return *this; }
//@}
//@{
/// Unset options defined in _rhs.
Options& operator -= ( const value_type _rhs )
{ flags_ &= ~_rhs; return *this; }
Options& unset( const value_type _rhs)
{ return (*this -= _rhs); }
//@}
//@{
/// Set options defined in _rhs
Options& operator += ( const value_type _rhs )
{ flags_ |= _rhs; return *this; }
Options& set( const value_type _rhs)
{ return (*this += _rhs); }
//@}
public:
// Check if an option or several options are set.
bool check(const value_type _rhs) const
{
return (flags_ & _rhs)==_rhs;
}
bool is_binary() const { return check(Binary); }
bool vertex_has_normal() const { return check(VertexNormal); }
bool vertex_has_color() const { return check(VertexColor); }
bool vertex_has_texcoord() const { return check(VertexTexCoord); }
bool edge_has_color() const { return check(EdgeColor); }
bool face_has_normal() const { return check(FaceNormal); }
bool face_has_color() const { return check(FaceColor); }
bool face_has_texcoord() const { return check(FaceTexCoord); }
bool color_has_alpha() const { return check(ColorAlpha); }
bool color_is_float() const { return check(ColorFloat); }
/// Returns true if _rhs has the same options enabled.
bool operator == (const value_type _rhs) const
{ return flags_ == _rhs; }
/// Returns true if _rhs does not have the same options enabled.
bool operator != (const value_type _rhs) const
{ return flags_ != _rhs; }
/// Returns the option set.
operator value_type () const { return flags_; }
private:
bool operator && (const value_type _rhs) const;
value_type flags_;
};
//-----------------------------------------------------------------------------
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,136 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_SR_BINARY_HH
#define OPENMESH_SR_BINARY_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
// -------------------- STL
#include <typeinfo>
#include <stdexcept>
#include <sstream>
#include <numeric> // accumulate
// -------------------- OpenMesh
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
//-----------------------------------------------------------------------------
const static size_t UnknownSize(size_t(-1));
//-----------------------------------------------------------------------------
// struct binary, helper for storing/restoring
#define X \
std::ostringstream msg; \
msg << "Type not supported: " << typeid(value_type).name(); \
throw std::logic_error(msg.str())
/// \struct binary SR_binary.hh <OpenMesh/Core/IO/SR_binary.hh>
///
/// The struct defines how to store and restore the type T.
/// It's used by the OM reader/writer modules.
///
/// The following specialization are provided:
/// - Fundamental types except \c long \c double
/// - %OpenMesh vector types
/// - %OpenMesh::StatusInfo
/// - std::string (max. length 65535)
///
/// \todo Complete documentation of members
template < typename T > struct binary
{
typedef T value_type;
static const bool is_streamable = false;
static size_t size_of(void) { return UnknownSize; }
static size_t size_of(const value_type&) { return UnknownSize; }
static
size_t store( std::ostream& /* _os */,
const value_type& /* _v */,
bool /* _swap=false */)
{ X; return 0; }
static
size_t restore( std::istream& /* _is */,
value_type& /* _v */,
bool /* _swap=false */)
{ X; return 0; }
};
#undef X
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_SR_RBO_HH defined
//=============================================================================

View File

@ -0,0 +1,329 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_SR_BINARY_SPEC_HH
#define OPENMESH_SR_BINARY_SPEC_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
// -------------------- STL
#include <iterator>
#include <string>
#if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000)
# include <OpenMesh/Tools/Utils/NumLimitsT.hh>
#else
# include <limits>
#endif
#include <vector>
#include <stdexcept> // logic_error
#include <numeric> // accumulate
// -------------------- OpenMesh
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Mesh/Status.hh>
#include <OpenMesh/Core/IO/SR_types.hh>
#include <OpenMesh/Core/IO/SR_rbo.hh>
#include <OpenMesh/Core/IO/SR_binary.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
#ifndef DOXY_IGNORE_THIS
//-----------------------------------------------------------------------------
// struct binary, helper for storing/restoring
#define SIMPLE_BINARY( T ) \
template <> struct binary< T > { \
typedef T value_type; \
static const bool is_streamable = true; \
static size_t size_of(const value_type&) { return sizeof(value_type); } \
static size_t size_of(void) { return sizeof(value_type); } \
static size_t store( std::ostream& _os, const value_type& _val, \
bool _swap=false) { \
value_type tmp = _val; \
if (_swap) reverse_byte_order(tmp); \
_os.write( (const char*)&tmp, sizeof(value_type) ); \
return _os.good() ? sizeof(value_type) : 0; \
} \
\
static size_t restore( std::istream& _is, value_type& _val, \
bool _swap=false) { \
_is.read( (char*)&_val, sizeof(value_type) ); \
if (_swap) reverse_byte_order(_val); \
return _is.good() ? sizeof(value_type) : 0; \
} \
}
SIMPLE_BINARY(bool);
//SIMPLE_BINARY(int);
// Why is this needed? Should not be used as not 32 bit compatible
//SIMPLE_BINARY(unsigned long);
SIMPLE_BINARY(float);
SIMPLE_BINARY(double);
SIMPLE_BINARY(long double);
SIMPLE_BINARY(char);
SIMPLE_BINARY(int8_t);
SIMPLE_BINARY(int16_t);
SIMPLE_BINARY(int32_t);
SIMPLE_BINARY(int64_t);
SIMPLE_BINARY(uint8_t);
SIMPLE_BINARY(uint16_t);
SIMPLE_BINARY(uint32_t);
SIMPLE_BINARY(uint64_t);
#undef SIMPLE_BINARY
// For unsigned long which is of size 64 bit on 64 bit
// architectures: convert into 32 bit unsigned integer value
// in order to stay compatible between 32/64 bit architectures.
// This allows cross reading BUT forbids storing unsigned longs
// as data type since higher order word (4 bytes) will be truncated.
// Does not work in case the data type that is to be stored
// exceeds the value range of unsigned int in size, which is improbable...
#define SIMPLE_BINARY( T ) \
template <> struct binary< T > { \
typedef T value_type; \
static const bool is_streamable = true; \
static size_t size_of(const value_type&) { return sizeof(value_type); } \
static size_t size_of(void) { return sizeof(value_type); } \
static size_t store( std::ostream& _os, const value_type& _val, \
bool _swap=false) { \
value_type tmp = _val; \
if (_swap) reverse_byte_order(tmp); \
/* Convert unsigned long to unsigned int for compatibility reasons */ \
unsigned int t1 = static_cast<unsigned int>(tmp); \
_os.write( (const char*)&t1, sizeof(unsigned int) ); \
return _os.good() ? sizeof(unsigned int) : 0; \
} \
\
static size_t restore( std::istream& _is, value_type& _val, \
bool _swap=false) { \
unsigned int t1; \
_is.read( (char*)&t1, sizeof(unsigned int) ); \
_val = t1; \
if (_swap) reverse_byte_order(_val); \
return _is.good() ? sizeof(unsigned int) : 0; \
} \
}
SIMPLE_BINARY(unsigned long);
#undef SIMPLE_BINARY
#define VECTORT_BINARY( T ) \
template <> struct binary< T > { \
typedef T value_type; \
static const bool is_streamable = true; \
static size_t size_of(void) { return sizeof(value_type); } \
static size_t size_of(const value_type&) { return size_of(); } \
static size_t store( std::ostream& _os, const value_type& _val, \
bool _swap=false) { \
value_type tmp = _val; \
size_t i, b = size_of(_val), N = value_type::size_; \
if (_swap) for (i=0; i<N; ++i) \
reverse_byte_order( tmp[i] ); \
_os.write( (const char*)&tmp[0], b ); \
return _os.good() ? b : 0; \
} \
\
static size_t restore( std::istream& _is, value_type& _val, \
bool _swap=false) { \
size_t i, N=value_type::size_; \
size_t b = N * sizeof(value_type::value_type); \
_is.read( (char*)&_val[0], b ); \
if (_swap) for (i=0; i<N; ++i) \
reverse_byte_order( _val[i] ); \
return _is.good() ? b : 0; \
} \
}
#define VECTORTS_BINARY( N ) \
VECTORT_BINARY( Vec##N##c ); \
VECTORT_BINARY( Vec##N##uc ); \
VECTORT_BINARY( Vec##N##s ); \
VECTORT_BINARY( Vec##N##us ); \
VECTORT_BINARY( Vec##N##i ); \
VECTORT_BINARY( Vec##N##ui ); \
VECTORT_BINARY( Vec##N##f ); \
VECTORT_BINARY( Vec##N##d );
VECTORTS_BINARY( 1 )
VECTORTS_BINARY( 2 )
VECTORTS_BINARY( 3 )
VECTORTS_BINARY( 4 )
VECTORTS_BINARY( 6 )
#undef VECTORTS_BINARY
#undef VECTORT_BINARY
template <> struct binary< std::string > {
typedef std::string value_type;
typedef uint16_t length_t;
static const bool is_streamable = true;
static size_t size_of() { return UnknownSize; }
static size_t size_of(const value_type &_v)
{ return sizeof(length_t) + _v.size(); }
static
size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
{
#if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000)
if (_v.size() < Utils::NumLimitsT<length_t>::max() )
#else
if (_v.size() < std::numeric_limits<length_t>::max() )
#endif
{
length_t len = length_t(_v.size());
size_t bytes = binary<length_t>::store( _os, len, _swap );
_os.write( _v.data(), len );
return _os.good() ? len+bytes : 0;
}
throw std::runtime_error("Cannot store string longer than 64Kb");
}
static
size_t restore(std::istream& _is, value_type& _val, bool _swap=false)
{
length_t len;
size_t bytes = binary<length_t>::restore( _is, len, _swap );
_val.resize(len);
_is.read( const_cast<char*>(_val.data()), len );
return _is.good() ? (len+bytes) : 0;
}
};
template <> struct binary<OpenMesh::Attributes::StatusInfo>
{
typedef OpenMesh::Attributes::StatusInfo value_type;
typedef value_type::value_type status_t;
static const bool is_streamable = true;
static size_t size_of() { return sizeof(status_t); }
static size_t size_of(const value_type&) { return size_of(); }
static size_t n_bytes(size_t _n_elem)
{ return _n_elem*sizeof(status_t); }
static
size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
{
status_t v=_v.bits();
return binary<status_t>::store(_os, v, _swap);
}
static
size_t restore( std::istream& _os, value_type& _v, bool _swap=false)
{
status_t v;
size_t b = binary<status_t>::restore(_os, v, _swap);
_v.set_bits(v);
return b;
}
};
//-----------------------------------------------------------------------------
// std::vector<T> specializations for struct binary<>
template <typename T>
struct FunctorStore {
FunctorStore( std::ostream& _os, bool _swap) : os_(_os), swap_(_swap) { }
size_t operator () ( size_t _v1, const T& _s2 )
{ return _v1+binary<T>::store(os_, _s2, swap_ ); }
std::ostream& os_;
bool swap_;
};
template <typename T>
struct FunctorRestore {
FunctorRestore( std::istream& _is, bool _swap) : is_(_is), swap_(_swap) { }
size_t operator () ( size_t _v1, T& _s2 )
{ return _v1+binary<T>::restore(is_, _s2, swap_ ); }
std::istream& is_;
bool swap_;
};
#include <OpenMesh/Core/IO/SR_binary_vector_of_fundamentals.inl>
#include <OpenMesh/Core/IO/SR_binary_vector_of_string.inl>
#include <OpenMesh/Core/IO/SR_binary_vector_of_bool.inl>
// ----------------------------------------------------------------------------
#endif // DOXY_IGNORE_THIS
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_SR_BINARY_SPEC_HH defined
//=============================================================================

View File

@ -0,0 +1,98 @@
template <> struct binary< std::vector<bool> >
{
typedef std::vector< bool > value_type;
typedef value_type::value_type elem_type;
static const bool is_streamable = true;
static size_t size_of(void) { return UnknownSize; }
static size_t size_of(const value_type& _v)
{
return _v.size() / 8 + ((_v.size() % 8)!=0);
}
static
size_t store( std::ostream& _ostr, const value_type& _v, bool )
{
size_t bytes = 0;
size_t N = _v.size() / 8;
size_t R = _v.size() % 8;
size_t idx; // element index
unsigned char bits; // bitset
for (idx=0; idx < N; ++idx)
{
bits = static_cast<unsigned char>(_v[idx])
| (static_cast<unsigned char>(_v[idx+1]) << 1)
| (static_cast<unsigned char>(_v[idx+2]) << 2)
| (static_cast<unsigned char>(_v[idx+3]) << 3)
| (static_cast<unsigned char>(_v[idx+4]) << 4)
| (static_cast<unsigned char>(_v[idx+5]) << 5)
| (static_cast<unsigned char>(_v[idx+6]) << 6)
| (static_cast<unsigned char>(_v[idx+7]) << 7);
_ostr << bits;
}
bytes = N;
if (R)
{
bits = 0;
switch(R)
{
case 7: bits |= (static_cast<unsigned char>(_v[idx+6]) << 6);
case 6: bits |= (static_cast<unsigned char>(_v[idx+5]) << 5);
case 5: bits |= (static_cast<unsigned char>(_v[idx+4]) << 4);
case 4: bits |= (static_cast<unsigned char>(_v[idx+3]) << 3);
case 3: bits |= (static_cast<unsigned char>(_v[idx+2]) << 2);
case 2: bits |= (static_cast<unsigned char>(_v[idx+1]) << 1);
case 1: bits |= static_cast<unsigned char>(_v[idx+0]);
}
_ostr << bits;
++bytes;
}
assert( bytes == size_of(_v) );
return bytes;
}
static
size_t restore( std::istream& _istr, value_type& _v, bool )
{
size_t bytes = 0;
size_t N = _v.size() / 8;
size_t R = _v.size() % 8;
size_t idx; // element index
unsigned char bits; // bitset
for (idx=0; idx < N; ++idx)
{
_istr >> bits;
_v[idx+0] = ((bits & 0x01)!=0);
_v[idx+1] = ((bits & 0x02)!=0);
_v[idx+2] = ((bits & 0x04)!=0);
_v[idx+3] = ((bits & 0x08)!=0);
_v[idx+4] = ((bits & 0x10)!=0);
_v[idx+5] = ((bits & 0x20)!=0);
_v[idx+6] = ((bits & 0x40)!=0);
_v[idx+7] = ((bits & 0x80)!=0);
}
bytes = N;
if (R)
{
_istr >> bits;
for(; idx < _v.size(); ++idx)
_v[idx] = (bits & (1 << (idx%8)))!=0;
++bytes;
}
return bytes;
}
};

View File

@ -0,0 +1,53 @@
#define BINARY_VECTOR( T ) \
template <> struct binary< std::vector< T > > { \
typedef std::vector< T > value_type; \
typedef value_type::value_type elem_type; \
\
static const bool is_streamable = true; \
\
static size_t size_of(void) \
{ return IO::UnknownSize; } \
\
static size_t size_of(const value_type& _v) \
{ return sizeof(elem_type)*_v.size(); } \
\
static \
size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) { \
size_t bytes=0; \
\
if (_swap) \
bytes = std::accumulate( _v.begin(), _v.end(), bytes, \
FunctorStore<elem_type>(_os,_swap) ); \
else { \
bytes = size_of(_v); \
_os.write( reinterpret_cast<const char*>(&_v[0]), bytes ); \
} \
return _os.good() ? bytes : 0; \
} \
\
static size_t restore(std::istream& _is, value_type& _v, bool _swap=false) { \
size_t bytes=0; \
\
if ( _swap) \
bytes = std::accumulate( _v.begin(), _v.end(), size_t(0), \
FunctorRestore<elem_type>(_is, _swap) ); \
else \
{ \
bytes = size_of(_v); \
_is.read( reinterpret_cast<char*>(&_v[0]), bytes ); \
} \
return _is.good() ? bytes : 0; \
} \
}
BINARY_VECTOR( short );
BINARY_VECTOR( unsigned short );
BINARY_VECTOR( int );
BINARY_VECTOR( unsigned int );
BINARY_VECTOR( long );
BINARY_VECTOR( unsigned long );
BINARY_VECTOR( float );
BINARY_VECTOR( double );
#undef BINARY_VECTOR

View File

@ -0,0 +1,39 @@
template <> struct binary< std::vector< std::string > >
{
// struct binary interface
typedef std::vector< std::string > value_type;
typedef value_type::value_type elem_type;
static const bool is_streamable = true;
// Helper
struct Sum
{
size_t operator() ( size_t _v1, const elem_type& _s2 )
{ return _v1 + binary<elem_type>::size_of(_s2); }
};
// struct binary interface
static size_t size_of(void) { return UnknownSize; }
static size_t size_of(const value_type& _v)
{ return std::accumulate( _v.begin(), _v.end(), size_t(0), Sum() ); }
static
size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
{
return std::accumulate( _v.begin(), _v.end(), size_t(0),
FunctorStore<elem_type>(_os, _swap) );
}
static
size_t restore(std::istream& _is, value_type& _v, bool _swap=false)
{
return std::accumulate( _v.begin(), _v.end(), size_t(0),
FunctorRestore<elem_type>(_is, _swap) );
}
};

View File

@ -0,0 +1,256 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_SR_RBO_HH
#define OPENMESH_SR_RBO_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
// -------------------- STL
#if defined(OM_CC_MIPS)
# include <stdio.h> // size_t
#else
# include <cstdio> // size_t
#endif
#include <algorithm>
#include <typeinfo>
// -------------------- OpenMesh
#include <OpenMesh/Core/System/omstream.hh>
#include <OpenMesh/Core/IO/SR_types.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
/** \name Handling binary input/output.
These functions take care of swapping bytes to get the right Endian.
*/
//@{
//-----------------------------------------------------------------------------
/** this does not compile for g++3.4 and higher, hence we comment the
function body which will result in a linker error */
template < size_t N > inline
void _reverse_byte_order_N(uint8_t* _val);
template <> inline
void _reverse_byte_order_N<1>(uint8_t* /*_val*/) { }
template <> inline
void _reverse_byte_order_N<2>(uint8_t* _val)
{
_val[0] ^= _val[1]; _val[1] ^= _val[0]; _val[0] ^= _val[1];
}
template <> inline
void _reverse_byte_order_N<4>(uint8_t* _val)
{
_val[0] ^= _val[3]; _val[3] ^= _val[0]; _val[0] ^= _val[3]; // 0 <-> 3
_val[1] ^= _val[2]; _val[2] ^= _val[1]; _val[1] ^= _val[2]; // 1 <-> 2
}
template <> inline
void _reverse_byte_order_N<8>(uint8_t* _val)
{
_val[0] ^= _val[7]; _val[7] ^= _val[0]; _val[0] ^= _val[7]; // 0 <-> 7
_val[1] ^= _val[6]; _val[6] ^= _val[1]; _val[1] ^= _val[6]; // 1 <-> 6
_val[2] ^= _val[5]; _val[5] ^= _val[2]; _val[2] ^= _val[5]; // 2 <-> 5
_val[3] ^= _val[4]; _val[4] ^= _val[3]; _val[3] ^= _val[4]; // 3 <-> 4
}
template <> inline
void _reverse_byte_order_N<12>(uint8_t* _val)
{
_val[0] ^= _val[11]; _val[11] ^= _val[0]; _val[0] ^= _val[11]; // 0 <-> 11
_val[1] ^= _val[10]; _val[10] ^= _val[1]; _val[1] ^= _val[10]; // 1 <-> 10
_val[2] ^= _val[ 9]; _val[ 9] ^= _val[2]; _val[2] ^= _val[ 9]; // 2 <-> 9
_val[3] ^= _val[ 8]; _val[ 8] ^= _val[3]; _val[3] ^= _val[ 8]; // 3 <-> 8
_val[4] ^= _val[ 7]; _val[ 7] ^= _val[4]; _val[4] ^= _val[ 7]; // 4 <-> 7
_val[5] ^= _val[ 6]; _val[ 6] ^= _val[5]; _val[5] ^= _val[ 6]; // 5 <-> 6
}
template <> inline
void _reverse_byte_order_N<16>(uint8_t* _val)
{
_reverse_byte_order_N<8>(_val);
_reverse_byte_order_N<8>(_val+8);
std::swap(*(uint64_t*)_val, *(((uint64_t*)_val)+1));
}
//-----------------------------------------------------------------------------
// wrapper for byte reordering
// reverting pointers makes no sense, hence forbid it.
/** this does not compile for g++3.4 and higher, hence we comment the
function body which will result in a linker error */
template <typename T> inline T* reverse_byte_order(T* t);
// Should never reach this point. If so, then some operator were not
// overloaded. Especially check for IO::binary<> specialization on
// custom data types.
inline void compile_time_error__no_fundamental_type()
{
// we should never reach this point
assert(false);
}
// default action for byte reversal: cause an error to avoid
// surprising behaviour!
template <typename T> T& reverse_byte_order( T& _t )
{
omerr() << "Not defined for type " << typeid(T).name() << std::endl;
compile_time_error__no_fundamental_type();
return _t;
}
template <> inline bool& reverse_byte_order(bool & _t) { return _t; }
template <> inline char& reverse_byte_order(char & _t) { return _t; }
#if defined(OM_CC_GCC)
template <> inline signed char& reverse_byte_order(signed char & _t) { return _t; }
#endif
template <> inline uchar& reverse_byte_order(uchar& _t) { return _t; }
// Instead do specializations for the necessary types
#define REVERSE_FUNDAMENTAL_TYPE( T ) \
template <> inline T& reverse_byte_order( T& _t ) {\
_reverse_byte_order_N<sizeof(T)>( reinterpret_cast<uint8_t*>(&_t) ); \
return _t; \
}
// REVERSE_FUNDAMENTAL_TYPE(bool)
// REVERSE_FUNDAMENTAL_TYPE(char)
// REVERSE_FUNDAMENTAL_TYPE(uchar)
REVERSE_FUNDAMENTAL_TYPE(int16_t)
REVERSE_FUNDAMENTAL_TYPE(uint16_t)
// REVERSE_FUNDAMENTAL_TYPE(int)
// REVERSE_FUNDAMENTAL_TYPE(uint)
REVERSE_FUNDAMENTAL_TYPE(unsigned long)
REVERSE_FUNDAMENTAL_TYPE(int32_t)
REVERSE_FUNDAMENTAL_TYPE(uint32_t)
REVERSE_FUNDAMENTAL_TYPE(int64_t)
REVERSE_FUNDAMENTAL_TYPE(uint64_t)
REVERSE_FUNDAMENTAL_TYPE(float)
REVERSE_FUNDAMENTAL_TYPE(double)
REVERSE_FUNDAMENTAL_TYPE(long double)
#undef REVERSE_FUNDAMENTAL_TYPE
#if 0
#define REVERSE_VECTORT_TYPE( T ) \
template <> inline T& reverse_byte_order(T& _v) {\
for (size_t i; i< T::size_; ++i) \
_reverse_byte_order_N< sizeof(T::value_type) >( reinterpret_cast<uint8_t*>(&_v[i])); \
return _v; \
}
#define REVERSE_VECTORT_TYPES( N ) \
REVERSE_VECTORT_TYPE( Vec##N##c ) \
REVERSE_VECTORT_TYPE( Vec##N##uc ) \
REVERSE_VECTORT_TYPE( Vec##N##s ) \
REVERSE_VECTORT_TYPE( Vec##N##us ) \
REVERSE_VECTORT_TYPE( Vec##N##i ) \
REVERSE_VECTORT_TYPE( Vec##N##ui ) \
REVERSE_VECTORT_TYPE( Vec##N##f ) \
REVERSE_VECTORT_TYPE( Vec##N##d ) \
REVERSE_VECTORT_TYPES(1)
REVERSE_VECTORT_TYPES(2)
REVERSE_VECTORT_TYPES(3)
REVERSE_VECTORT_TYPES(4)
REVERSE_VECTORT_TYPES(6)
#undef REVERSE_VECTORT_TYPES
#undef REVERSE_VECTORT_TYPE
#endif
template <typename T> inline
T reverse_byte_order(const T& a)
{
compile_timer_error__const_means_const(a);
return a;
}
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_SR_RBO_HH defined
//=============================================================================

View File

@ -0,0 +1,72 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_SR_STORE_HH
#define OPENMESH_SR_STORE_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/IO/SR_types.hh>
#include <OpenMesh/Core/IO/SR_rbo.hh>
#include <OpenMesh/Core/IO/SR_binary.hh>
#include <OpenMesh/Core/IO/SR_binary_spec.hh>
#include <OpenMesh/Core/IO/StoreRestore.hh>
//=============================================================================
#endif // OPENMESH_STORE_HH defined
//=============================================================================

View File

@ -0,0 +1,112 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_SR_TYPES_HH
#define OPENMESH_SR_TYPES_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
/** \name Handling binary input/output.
These functions take care of swapping bytes to get the right Endian.
*/
//@{
//-----------------------------------------------------------------------------
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef signed char int8_t; typedef unsigned char uint8_t;
typedef short int16_t; typedef unsigned short uint16_t;
// Int should be 32 bit on all archs.
// long is 32 under windows but 64 under unix 64 bit
typedef int int32_t; typedef unsigned int uint32_t;
#if defined(OM_CC_MSVC)
typedef __int64 int64_t; typedef unsigned __int64 uint64_t;
#else
typedef long long int64_t; typedef unsigned long long uint64_t;
#endif
typedef float float32_t;
typedef double float64_t;
typedef uint8_t rgb_t[3];
typedef uint8_t rgba_t[4];
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_MESHREADER_HH defined
//=============================================================================

View File

@ -0,0 +1,117 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Helper Functions for binary reading / writing
//
//=============================================================================
#ifndef OPENMESH_STORERESTORE_HH
#define OPENMESH_STORERESTORE_HH
//== INCLUDES =================================================================
#include <stdexcept>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/IO/SR_binary.hh>
#include <OpenMesh/Core/IO/SR_binary_spec.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=============================================================================
/** \name Handling binary input/output.
These functions take care of swapping bytes to get the right Endian.
*/
//@{
//-----------------------------------------------------------------------------
// StoreRestore definitions
template <typename T> inline
bool is_streamable(void)
{ return binary< T >::is_streamable; }
template <typename T> inline
bool is_streamable( const T& )
{ return binary< T >::is_streamable; }
template <typename T> inline
size_t size_of( const T& _v )
{ return binary< T >::size_of(_v); }
template <typename T> inline
size_t size_of(void)
{ return binary< T >::size_of(); }
template <typename T> inline
size_t store( std::ostream& _os, const T& _v, bool _swap=false)
{ return binary< T >::store( _os, _v, _swap ); }
template <typename T> inline
size_t restore( std::istream& _is, T& _v, bool _swap=false)
{ return binary< T >::restore( _is, _v, _swap ); }
//@}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_MESHREADER_HH defined
//=============================================================================

View File

@ -0,0 +1,165 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements the baseclass for MeshWriter exporter modules
//
//=============================================================================
#ifndef __BASEEXPORTER_HH__
#define __BASEEXPORTER_HH__
//=== INCLUDES ================================================================
// STL
#include <vector>
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Mesh/BaseKernel.hh>
//=== NAMESPACES ==============================================================
namespace OpenMesh {
namespace IO {
//=== EXPORTER ================================================================
/**
Base class for exporter modules.
The exporter modules provide an interface between the writer modules and
the target data structure.
*/
class OPENMESHDLLEXPORT BaseExporter
{
public:
virtual ~BaseExporter() { }
// get vertex data
virtual Vec3f point(VertexHandle _vh) const = 0;
virtual Vec3f normal(VertexHandle _vh) const = 0;
virtual Vec3uc color(VertexHandle _vh) const = 0;
virtual Vec4uc colorA(VertexHandle _vh) const = 0;
virtual Vec3ui colori(VertexHandle _vh) const = 0;
virtual Vec4ui colorAi(VertexHandle _vh) const = 0;
virtual Vec3f colorf(VertexHandle _vh) const = 0;
virtual Vec4f colorAf(VertexHandle _vh) const = 0;
virtual Vec2f texcoord(VertexHandle _vh) const = 0;
virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0;
// get face data
virtual unsigned int
get_vhandles(FaceHandle _fh,
std::vector<VertexHandle>& _vhandles) const=0;
///
/// \brief getHeh returns the HalfEdgeHandle that belongs to the face
/// specified by _fh and has a toVertexHandle that corresponds to _vh.
/// \param _fh FaceHandle that is used to search for the half edge handle
/// \param _vh to_vertex_handle of the searched heh
/// \return HalfEdgeHandle or invalid HalfEdgeHandle if none is found.
///
virtual HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const = 0;
virtual unsigned int
get_face_texcoords(std::vector<Vec2f>& _hehandles) const = 0;
virtual Vec3f normal(FaceHandle _fh) const = 0;
virtual Vec3uc color (FaceHandle _fh) const = 0;
virtual Vec4uc colorA(FaceHandle _fh) const = 0;
virtual Vec3ui colori(FaceHandle _fh) const = 0;
virtual Vec4ui colorAi(FaceHandle _fh) const = 0;
virtual Vec3f colorf(FaceHandle _fh) const = 0;
virtual Vec4f colorAf(FaceHandle _fh) const = 0;
// get edge data
virtual Vec3uc color(EdgeHandle _eh) const = 0;
virtual Vec4uc colorA(EdgeHandle _eh) const = 0;
virtual Vec3ui colori(EdgeHandle _eh) const = 0;
virtual Vec4ui colorAi(EdgeHandle _eh) const = 0;
virtual Vec3f colorf(EdgeHandle _eh) const = 0;
virtual Vec4f colorAf(EdgeHandle _eh) const = 0;
// get reference to base kernel
virtual const BaseKernel* kernel() { return 0; }
// query number of faces, vertices, normals, texcoords
virtual size_t n_vertices() const = 0;
virtual size_t n_faces() const = 0;
virtual size_t n_edges() const = 0;
// property information
virtual bool is_triangle_mesh() const { return false; }
virtual bool has_vertex_normals() const { return false; }
virtual bool has_vertex_colors() const { return false; }
virtual bool has_vertex_texcoords() const { return false; }
virtual bool has_edge_colors() const { return false; }
virtual bool has_face_normals() const { return false; }
virtual bool has_face_colors() const { return false; }
};
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,338 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements an exporter module for arbitrary OpenMesh meshes
//
//=============================================================================
#ifndef __EXPORTERT_HH__
#define __EXPORTERT_HH__
//=== INCLUDES ================================================================
// C++
#include <vector>
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Core/Utils/color_cast.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
//=== NAMESPACES ==============================================================
namespace OpenMesh {
namespace IO {
//=== EXPORTER CLASS ==========================================================
/**
* This class template provides an exporter module for OpenMesh meshes.
*/
template <class Mesh>
class ExporterT : public BaseExporter
{
public:
// Constructor
ExporterT(const Mesh& _mesh) : mesh_(_mesh) {}
// get vertex data
Vec3f point(VertexHandle _vh) const
{
return vector_cast<Vec3f>(mesh_.point(_vh));
}
Vec3f normal(VertexHandle _vh) const
{
return (mesh_.has_vertex_normals()
? vector_cast<Vec3f>(mesh_.normal(_vh))
: Vec3f(0.0f, 0.0f, 0.0f));
}
Vec3uc color(VertexHandle _vh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec3uc>(mesh_.color(_vh))
: Vec3uc(0, 0, 0));
}
Vec4uc colorA(VertexHandle _vh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec4uc>(mesh_.color(_vh))
: Vec4uc(0, 0, 0, 0));
}
Vec3ui colori(VertexHandle _vh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec3ui>(mesh_.color(_vh))
: Vec3ui(0, 0, 0));
}
Vec4ui colorAi(VertexHandle _vh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec4ui>(mesh_.color(_vh))
: Vec4ui(0, 0, 0, 0));
}
Vec3f colorf(VertexHandle _vh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec3f>(mesh_.color(_vh))
: Vec3f(0, 0, 0));
}
Vec4f colorAf(VertexHandle _vh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec4f>(mesh_.color(_vh))
: Vec4f(0, 0, 0, 0));
}
Vec2f texcoord(VertexHandle _vh) const
{
#if defined(OM_CC_GCC) && (OM_CC_VERSION<30000)
// Workaround!
// gcc 2.95.3 exits with internal compiler error at the
// code below!??? **)
if (mesh_.has_vertex_texcoords2D())
return vector_cast<Vec2f>(mesh_.texcoord2D(_vh));
return Vec2f(0.0f, 0.0f);
#else // **)
return (mesh_.has_vertex_texcoords2D()
? vector_cast<Vec2f>(mesh_.texcoord2D(_vh))
: Vec2f(0.0f, 0.0f));
#endif
}
Vec2f texcoord(HalfedgeHandle _heh) const
{
return (mesh_.has_halfedge_texcoords2D()
? vector_cast<Vec2f>(mesh_.texcoord2D(_heh))
: Vec2f(0.0f, 0.0f));
}
// get edge data
Vec3uc color(EdgeHandle _eh) const
{
return (mesh_.has_edge_colors()
? color_cast<Vec3uc>(mesh_.color(_eh))
: Vec3uc(0, 0, 0));
}
Vec4uc colorA(EdgeHandle _eh) const
{
return (mesh_.has_edge_colors()
? color_cast<Vec4uc>(mesh_.color(_eh))
: Vec4uc(0, 0, 0, 0));
}
Vec3ui colori(EdgeHandle _eh) const
{
return (mesh_.has_edge_colors()
? color_cast<Vec3ui>(mesh_.color(_eh))
: Vec3ui(0, 0, 0));
}
Vec4ui colorAi(EdgeHandle _eh) const
{
return (mesh_.has_edge_colors()
? color_cast<Vec4ui>(mesh_.color(_eh))
: Vec4ui(0, 0, 0, 0));
}
Vec3f colorf(EdgeHandle _eh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec3f>(mesh_.color(_eh))
: Vec3f(0, 0, 0));
}
Vec4f colorAf(EdgeHandle _eh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec4f>(mesh_.color(_eh))
: Vec4f(0, 0, 0, 0));
}
// get face data
unsigned int get_vhandles(FaceHandle _fh,
std::vector<VertexHandle>& _vhandles) const
{
unsigned int count(0);
_vhandles.clear();
for (typename Mesh::CFVIter fv_it=mesh_.cfv_iter(_fh); fv_it.is_valid(); ++fv_it)
{
_vhandles.push_back(*fv_it);
++count;
}
return count;
}
unsigned int get_face_texcoords(std::vector<Vec2f>& _hehandles) const
{
unsigned int count(0);
_hehandles.clear();
for(typename Mesh::CHIter he_it=mesh_.halfedges_begin();
he_it != mesh_.halfedges_end(); ++he_it)
{
_hehandles.push_back(vector_cast<Vec2f>(mesh_.texcoord2D( *he_it)));
++count;
}
return count;
}
HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const
{
typename Mesh::ConstFaceHalfedgeIter fh_it;
for(fh_it = mesh_.cfh_iter(_fh); fh_it.is_valid();++fh_it)
{
if(mesh_.to_vertex_handle(*fh_it) == _vh)
return *fh_it;
}
return *fh_it;
}
Vec3f normal(FaceHandle _fh) const
{
return (mesh_.has_face_normals()
? vector_cast<Vec3f>(mesh_.normal(_fh))
: Vec3f(0.0f, 0.0f, 0.0f));
}
Vec3uc color(FaceHandle _fh) const
{
return (mesh_.has_face_colors()
? color_cast<Vec3uc>(mesh_.color(_fh))
: Vec3uc(0, 0, 0));
}
Vec4uc colorA(FaceHandle _fh) const
{
return (mesh_.has_face_colors()
? color_cast<Vec4uc>(mesh_.color(_fh))
: Vec4uc(0, 0, 0, 0));
}
Vec3ui colori(FaceHandle _fh) const
{
return (mesh_.has_face_colors()
? color_cast<Vec3ui>(mesh_.color(_fh))
: Vec3ui(0, 0, 0));
}
Vec4ui colorAi(FaceHandle _fh) const
{
return (mesh_.has_face_colors()
? color_cast<Vec4ui>(mesh_.color(_fh))
: Vec4ui(0, 0, 0, 0));
}
Vec3f colorf(FaceHandle _fh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec3f>(mesh_.color(_fh))
: Vec3f(0, 0, 0));
}
Vec4f colorAf(FaceHandle _fh) const
{
return (mesh_.has_vertex_colors()
? color_cast<Vec4f>(mesh_.color(_fh))
: Vec4f(0, 0, 0, 0));
}
virtual const BaseKernel* kernel() { return &mesh_; }
// query number of faces, vertices, normals, texcoords
size_t n_vertices() const { return mesh_.n_vertices(); }
size_t n_faces() const { return mesh_.n_faces(); }
size_t n_edges() const { return mesh_.n_edges(); }
// property information
bool is_triangle_mesh() const
{ return Mesh::is_triangles(); }
bool has_vertex_normals() const { return mesh_.has_vertex_normals(); }
bool has_vertex_colors() const { return mesh_.has_vertex_colors(); }
bool has_vertex_texcoords() const { return mesh_.has_vertex_texcoords2D(); }
bool has_edge_colors() const { return mesh_.has_edge_colors(); }
bool has_face_normals() const { return mesh_.has_face_normals(); }
bool has_face_colors() const { return mesh_.has_face_colors(); }
private:
const Mesh& mesh_;
};
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,205 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements the baseclass for IOManager importer modules
//
//=============================================================================
#ifndef __BASEIMPORTER_HH__
#define __BASEIMPORTER_HH__
//=== INCLUDES ================================================================
// STL
#include <vector>
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Geometry/VectorT.hh>
#include <OpenMesh/Core/Mesh/BaseKernel.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/** Base class for importer modules. Importer modules provide an
* interface between the loader modules and the target data
* structure. This is basically a wrapper providing virtual versions
* for the required mesh functions.
*/
class OPENMESHDLLEXPORT BaseImporter
{
public:
// base class needs virtual destructor
virtual ~BaseImporter() {}
// add a vertex with coordinate \c _point
virtual VertexHandle add_vertex(const Vec3f& _point) = 0;
// add a vertex without coordinate. Use set_point to set the position deferred
virtual VertexHandle add_vertex() = 0;
// add a face with indices _indices refering to vertices
typedef std::vector<VertexHandle> VHandles;
virtual FaceHandle add_face(const VHandles& _indices) = 0;
// add texture coordinates per face, _vh references the first texcoord
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords) = 0;
// add texture 3d coordinates per face, _vh references the first texcoord
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords) = 0;
// Set the texture index for a face
virtual void set_face_texindex( FaceHandle _fh, int _texId ) = 0;
// Set coordinate of the given vertex. Use this function, if you created a vertex without coordinate
virtual void set_point(VertexHandle _vh, const Vec3f& _point) = 0;
// set vertex normal
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0;
// set vertex color
virtual void set_color(VertexHandle _vh, const Vec3uc& _color) = 0;
// set vertex color
virtual void set_color(VertexHandle _vh, const Vec4uc& _color) = 0;
// set vertex color
virtual void set_color(VertexHandle _vh, const Vec3f& _color) = 0;
// set vertex color
virtual void set_color(VertexHandle _vh, const Vec4f& _color) = 0;
// set vertex texture coordinate
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0;
// set vertex texture coordinate
virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) = 0;
// set 3d vertex texture coordinate
virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) = 0;
// set 3d vertex texture coordinate
virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) = 0;
// set edge color
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0;
// set edge color
virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) = 0;
// set edge color
virtual void set_color(EdgeHandle _eh, const Vec3f& _color) = 0;
// set edge color
virtual void set_color(EdgeHandle _eh, const Vec4f& _color) = 0;
// set face normal
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0;
// set face color
virtual void set_color(FaceHandle _fh, const Vec3uc& _color) = 0;
// set face color
virtual void set_color(FaceHandle _fh, const Vec4uc& _color) = 0;
// set face color
virtual void set_color(FaceHandle _fh, const Vec3f& _color) = 0;
// set face color
virtual void set_color(FaceHandle _fh, const Vec4f& _color) = 0;
// Store a property in the mesh mapping from an int to a texture file
// Use set_face_texindex to set the index for each face
virtual void add_texture_information( int _id , std::string _name ) = 0;
// get reference to base kernel
virtual BaseKernel* kernel() { return 0; }
virtual bool is_triangle_mesh() const { return false; }
// reserve mem for elements
virtual void reserve( unsigned int /* nV */,
unsigned int /* nE */,
unsigned int /* nF */) {}
// query number of faces, vertices, normals, texcoords
virtual size_t n_vertices() const = 0;
virtual size_t n_faces() const = 0;
virtual size_t n_edges() const = 0;
// pre-processing
virtual void prepare() {}
// post-processing
virtual void finish() {}
};
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,408 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements an importer module for arbitrary OpenMesh meshes
//
//=============================================================================
#ifndef __IMPORTERT_HH__
#define __IMPORTERT_HH__
//=== INCLUDES ================================================================
#include <OpenMesh/Core/IO/importer/BaseImporter.hh>
#include <OpenMesh/Core/Utils/vector_cast.hh>
#include <OpenMesh/Core/Utils/color_cast.hh>
#include <OpenMesh/Core/Mesh/Attributes.hh>
#include <OpenMesh/Core/System/omstream.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
* This class template provides an importer module for OpenMesh meshes.
*/
template <class Mesh>
class ImporterT : public BaseImporter
{
public:
typedef typename Mesh::Point Point;
typedef typename Mesh::Normal Normal;
typedef typename Mesh::Color Color;
typedef typename Mesh::TexCoord2D TexCoord2D;
typedef typename Mesh::TexCoord3D TexCoord3D;
typedef std::vector<VertexHandle> VHandles;
ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {}
virtual VertexHandle add_vertex(const Vec3f& _point)
{
return mesh_.add_vertex(vector_cast<Point>(_point));
}
virtual VertexHandle add_vertex()
{
return mesh_.new_vertex();
}
virtual FaceHandle add_face(const VHandles& _indices)
{
FaceHandle fh;
if (_indices.size() > 2)
{
VHandles::const_iterator it, it2, end(_indices.end());
// test for valid vertex indices
for (it=_indices.begin(); it!=end; ++it)
if (! mesh_.is_valid_handle(*it))
{
omerr() << "ImporterT: Face contains invalid vertex index\n";
return fh;
}
// don't allow double vertices
for (it=_indices.begin(); it!=end; ++it)
for (it2=it+1; it2!=end; ++it2)
if (*it == *it2)
{
omerr() << "ImporterT: Face has equal vertices\n";
return fh;
}
// try to add face
fh = mesh_.add_face(_indices);
// separate non-manifold faces and mark them
if (!fh.is_valid())
{
VHandles vhandles(_indices.size());
// double vertices
for (unsigned int j=0; j<_indices.size(); ++j)
{
// DO STORE p, reference may not work since vertex array
// may be relocated after adding a new vertex !
Point p = mesh_.point(_indices[j]);
vhandles[j] = mesh_.add_vertex(p);
// Mark vertices of failed face as non-manifold
if (mesh_.has_vertex_status()) {
mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
}
}
// add face
fh = mesh_.add_face(vhandles);
// Mark failed face as non-manifold
if (mesh_.has_face_status())
mesh_.status(fh).set_fixed_nonmanifold(true);
// Mark edges of failed face as non-two-manifold
if (mesh_.has_edge_status()) {
typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);
for(; fe_it.is_valid(); ++fe_it) {
mesh_.status(*fe_it).set_fixed_nonmanifold(true);
}
}
}
//write the half edge normals
if (mesh_.has_halfedge_normals())
{
//iterate over all incoming haldedges of the added face
for (typename Mesh::FaceHalfedgeIter fh_iter = mesh_.fh_begin(fh);
fh_iter != mesh_.fh_end(fh); ++fh_iter)
{
//and write the normals to it
typename Mesh::HalfedgeHandle heh = *fh_iter;
typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(heh);
typename std::map<VertexHandle,Normal>::iterator it_heNs = halfedgeNormals_.find(vh);
if (it_heNs != halfedgeNormals_.end())
mesh_.set_normal(heh,it_heNs->second);
}
halfedgeNormals_.clear();
}
}
return fh;
}
// vertex attributes
virtual void set_point(VertexHandle _vh, const Vec3f& _point)
{
mesh_.set_point(_vh,vector_cast<Point>(_point));
}
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal)
{
if (mesh_.has_vertex_normals())
mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
//saves normals for half edges.
//they will be written, when the face is added
if (mesh_.has_halfedge_normals())
halfedgeNormals_[_vh] = vector_cast<Normal>(_normal);
}
virtual void set_color(VertexHandle _vh, const Vec4uc& _color)
{
if (mesh_.has_vertex_colors())
mesh_.set_color(_vh, color_cast<Color>(_color));
}
virtual void set_color(VertexHandle _vh, const Vec3uc& _color)
{
if (mesh_.has_vertex_colors())
mesh_.set_color(_vh, color_cast<Color>(_color));
}
virtual void set_color(VertexHandle _vh, const Vec4f& _color)
{
if (mesh_.has_vertex_colors())
mesh_.set_color(_vh, color_cast<Color>(_color));
}
virtual void set_color(VertexHandle _vh, const Vec3f& _color)
{
if (mesh_.has_vertex_colors())
mesh_.set_color(_vh, color_cast<Color>(_color));
}
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord)
{
if (mesh_.has_vertex_texcoords2D())
mesh_.set_texcoord2D(_vh, vector_cast<TexCoord2D>(_texcoord));
}
virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord)
{
if (mesh_.has_halfedge_texcoords2D())
mesh_.set_texcoord2D(_heh, vector_cast<TexCoord2D>(_texcoord));
}
virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord)
{
if (mesh_.has_vertex_texcoords3D())
mesh_.set_texcoord3D(_vh, vector_cast<TexCoord3D>(_texcoord));
}
virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord)
{
if (mesh_.has_halfedge_texcoords3D())
mesh_.set_texcoord3D(_heh, vector_cast<TexCoord3D>(_texcoord));
}
// edge attributes
virtual void set_color(EdgeHandle _eh, const Vec4uc& _color)
{
if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color));
}
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color)
{
if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color));
}
virtual void set_color(EdgeHandle _eh, const Vec4f& _color)
{
if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color));
}
virtual void set_color(EdgeHandle _eh, const Vec3f& _color)
{
if (mesh_.has_edge_colors())
mesh_.set_color(_eh, color_cast<Color>(_color));
}
// face attributes
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal)
{
if (mesh_.has_face_normals())
mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
}
virtual void set_color(FaceHandle _fh, const Vec3uc& _color)
{
if (mesh_.has_face_colors())
mesh_.set_color(_fh, color_cast<Color>(_color));
}
virtual void set_color(FaceHandle _fh, const Vec4uc& _color)
{
if (mesh_.has_face_colors())
mesh_.set_color(_fh, color_cast<Color>(_color));
}
virtual void set_color(FaceHandle _fh, const Vec3f& _color)
{
if (mesh_.has_face_colors())
mesh_.set_color(_fh, color_cast<Color>(_color));
}
virtual void set_color(FaceHandle _fh, const Vec4f& _color)
{
if (mesh_.has_face_colors())
mesh_.set_color(_fh, color_cast<Color>(_color));
}
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords)
{
// get first halfedge handle
HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
// find start heh
while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
cur_heh = mesh_.next_halfedge_handle( cur_heh);
for(unsigned int i=0; i<_face_texcoords.size(); ++i)
{
set_texcoord( cur_heh, _face_texcoords[i]);
cur_heh = mesh_.next_halfedge_handle( cur_heh);
}
}
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords)
{
// get first halfedge handle
HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
HalfedgeHandle end_heh = mesh_.prev_halfedge_handle(cur_heh);
// find start heh
while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
cur_heh = mesh_.next_halfedge_handle( cur_heh);
for(unsigned int i=0; i<_face_texcoords.size(); ++i)
{
set_texcoord( cur_heh, _face_texcoords[i]);
cur_heh = mesh_.next_halfedge_handle( cur_heh);
}
}
virtual void set_face_texindex( FaceHandle _fh, int _texId ) {
if ( mesh_.has_face_texture_index() ) {
mesh_.set_texture_index(_fh , _texId);
}
}
virtual void add_texture_information( int _id , std::string _name ) {
OpenMesh::MPropHandleT< std::map< int, std::string > > property;
if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
mesh_.add_property(property,"TextureMapping");
}
if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() )
mesh_.property(property)[_id] = _name;
}
// low-level access to mesh
virtual BaseKernel* kernel() { return &mesh_; }
bool is_triangle_mesh() const
{ return Mesh::is_triangles(); }
void reserve(unsigned int nV, unsigned int nE, unsigned int nF)
{
mesh_.reserve(nV, nE, nF);
}
// query number of faces, vertices, normals, texcoords
size_t n_vertices() const { return mesh_.n_vertices(); }
size_t n_faces() const { return mesh_.n_faces(); }
size_t n_edges() const { return mesh_.n_edges(); }
void prepare() { }
void finish() { }
private:
Mesh& mesh_;
// stores normals for halfedges of the next face
std::map<VertexHandle,Normal> halfedgeNormals_;
};
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,213 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements the baseclass for IOManager file access modules
//
//=============================================================================
#ifndef __BASEREADER_HH__
#define __BASEREADER_HH__
//=== INCLUDES ================================================================
// STD C++
#include <iosfwd>
#include <string>
#include <cctype>
#include <functional>
#include <algorithm>
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/IO/Options.hh>
#include <OpenMesh/Core/IO/importer/BaseImporter.hh>
#include <OpenMesh/Core/Utils/SingletonT.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
Base class for reader modules.
Reader modules access persistent data and pass them to the desired
data structure by the means of a BaseImporter derivative.
All reader modules must be derived from this class.
*/
class OPENMESHDLLEXPORT BaseReader
{
public:
/// Destructor
virtual ~BaseReader() {};
/// Returns a brief description of the file type that can be parsed.
virtual std::string get_description() const = 0;
/** Returns a string with the accepted file extensions separated by a
whitespace and in small caps.
*/
virtual std::string get_extensions() const = 0;
/// Return magic bits used to determine file format
virtual std::string get_magic() const { return std::string(""); }
/** Reads a mesh given by a filename. Usually this method opens a stream
and passes it to stream read method. Acceptance checks by filename
extension can be placed here.
Options can be passed via _opt. After execution _opt contains the Options
that were available
*/
virtual bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt) = 0;
/** Reads a mesh given by a std::stream. This method usually uses the same stream reading method
that read uses. Options can be passed via _opt. After execution _opt contains the Options
that were available.
Please make sure that if _is is std::ifstream, the correct std::ios_base::openmode flags are set.
*/
virtual bool read(std::istream& _is,
BaseImporter& _bi,
Options& _opt) = 0;
/** \brief Returns true if writer can parse _filename (checks extension).
* _filename can also provide an extension without a name for a file e.g. _filename == "om" checks, if the reader can read the "om" extension
* @param _filename complete name of a file or just the extension
* @result true, if reader can read data with the given extension
*/
virtual bool can_u_read(const std::string& _filename) const;
protected:
// case insensitive search for _ext in _fname.
bool check_extension(const std::string& _fname,
const std::string& _ext) const;
};
/** \brief Trim left whitespace
*
* Removes whitespace at the beginning of the string
*
* @param _string input string
* @return trimmed string
*/
static inline std::string &left_trim(std::string &_string) {
// Find out if the compiler supports CXX11
#if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L )
// as with CXX11 we can use lambda expressions
_string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), [](int i)->int { return ! std::isspace(i); }));
#else
// we do what we did before
_string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
#endif
return _string;
}
/** \brief Trim right whitespace
*
* Removes whitespace at the end of the string
*
* @param _string input string
* @return trimmed string
*/
static inline std::string &right_trim(std::string &_string) {
// Find out if the compiler supports CXX11
#if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L )
// as with CXX11 we can use lambda expressions
_string.erase(std::find_if(_string.rbegin(), _string.rend(), [](int i)->int { return ! std::isspace(i); } ).base(), _string.end());
#else
// we do what we did before
_string.erase(std::find_if(_string.rbegin(), _string.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _string.end());
#endif
return _string;
}
/** \brief Trim whitespace
*
* Removes whitespace at the beginning and end of the string
*
* @param _string input string
* @return trimmed string
*/
static inline std::string &trim(std::string &_string) {
return left_trim(right_trim(_string));
}
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,201 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements an reader module for OBJ files
//
//=============================================================================
#ifndef __OBJREADER_HH__
#define __OBJREADER_HH__
//=== INCLUDES ================================================================
#include <iosfwd>
#include <string>
#include <map>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/importer/BaseImporter.hh>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//== IMPLEMENTATION ===========================================================
/**
Implementation of the OBJ format reader.
*/
class OPENMESHDLLEXPORT _OBJReader_ : public BaseReader
{
public:
_OBJReader_();
virtual ~_OBJReader_() { }
std::string get_description() const { return "Alias/Wavefront"; }
std::string get_extensions() const { return "obj"; }
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt);
bool read(std::istream& _in,
BaseImporter& _bi,
Options& _opt);
private:
#ifndef DOXY_IGNORE_THIS
class Material
{
public:
Material() { cleanup(); }
void cleanup()
{
Kd_is_set_ = false;
Ka_is_set_ = false;
Ks_is_set_ = false;
Tr_is_set_ = false;
map_Kd_is_set_ = false;
}
bool is_valid(void) const
{ return Kd_is_set_ || Ka_is_set_ || Ks_is_set_ || Tr_is_set_ || map_Kd_is_set_; }
bool has_Kd(void) { return Kd_is_set_; }
bool has_Ka(void) { return Ka_is_set_; }
bool has_Ks(void) { return Ks_is_set_; }
bool has_Tr(void) { return Tr_is_set_; }
bool has_map_Kd(void) { return map_Kd_is_set_; }
void set_Kd( float r, float g, float b )
{ Kd_=Vec3f(r,g,b); Kd_is_set_=true; }
void set_Ka( float r, float g, float b )
{ Ka_=Vec3f(r,g,b); Ka_is_set_=true; }
void set_Ks( float r, float g, float b )
{ Ks_=Vec3f(r,g,b); Ks_is_set_=true; }
void set_Tr( float t )
{ Tr_=t; Tr_is_set_=true; }
void set_map_Kd( std::string _name, int _index_Kd )
{ map_Kd_ = _name, index_Kd_ = _index_Kd; map_Kd_is_set_ = true; };
const Vec3f& Kd( void ) const { return Kd_; }
const Vec3f& Ka( void ) const { return Ka_; }
const Vec3f& Ks( void ) const { return Ks_; }
float Tr( void ) const { return Tr_; }
const std::string& map_Kd( void ) { return map_Kd_ ; }
const int& map_Kd_index( void ) { return index_Kd_ ; }
private:
Vec3f Kd_; bool Kd_is_set_; // diffuse
Vec3f Ka_; bool Ka_is_set_; // ambient
Vec3f Ks_; bool Ks_is_set_; // specular
float Tr_; bool Tr_is_set_; // transperency
std::string map_Kd_; int index_Kd_; bool map_Kd_is_set_; // Texture
};
#endif
typedef std::map<std::string, Material> MaterialList;
MaterialList materials_;
bool read_material( std::fstream& _in );
private:
bool read_vertices(std::istream& _in, BaseImporter& _bi, Options& _opt,
std::vector<Vec3f> & normals,
std::vector<Vec3f> & colors,
std::vector<Vec3f> & texcoords3d,
std::vector<Vec2f> & texcoords,
std::vector<VertexHandle> & vertexHandles,
Options & fileOptions);
std::string path_;
};
//== TYPE DEFINITION ==========================================================
extern _OBJReader_ __OBJReaderInstance;
OPENMESHDLLEXPORT _OBJReader_& OBJReader();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,171 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a reader module for OFF files
//
//=============================================================================
#ifndef __OFFREADER_HH__
#define __OFFREADER_HH__
//=== INCLUDES ================================================================
#include <iosfwd>
#include <string>
#include <cstdio>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//== FORWARDS =================================================================
class BaseImporter;
//== IMPLEMENTATION ===========================================================
/**
Implementation of the OFF format reader. This class is singleton'ed by
SingletonT to OFFReader.
By passing Options to the read function you can manipulate the reading behavoir.
The following options can be set:
VertexNormal
VertexColor
VertexTexCoord
FaceColor
ColorAlpha [only when reading binary]
These options define if the corresponding data should be read (if available)
or if it should be omitted.
After execution of the read function. The options object contains information about
what was actually read.
e.g. if VertexNormal was true when the read function was called, but the file
did not contain vertex normals then it is false afterwards.
When reading a binary off with Color Flag in the header it is assumed that all vertices
and faces have colors in the format "int int int".
If ColorAlpha is set the format "int int int int" is assumed.
*/
class OPENMESHDLLEXPORT _OFFReader_ : public BaseReader
{
public:
_OFFReader_();
/// Destructor
virtual ~_OFFReader_() {};
std::string get_description() const { return "Object File Format"; }
std::string get_extensions() const { return "off"; }
std::string get_magic() const { return "OFF"; }
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt);
bool can_u_read(const std::string& _filename) const;
bool read(std::istream& _in, BaseImporter& _bi, Options& _opt );
private:
bool can_u_read(std::istream& _is) const;
bool read_ascii(std::istream& _in, BaseImporter& _bi, Options& _opt) const;
bool read_binary(std::istream& _in, BaseImporter& _bi, Options& _opt, bool swap) const;
void readValue(std::istream& _in, float& _value) const;
void readValue(std::istream& _in, int& _value) const;
void readValue(std::istream& _in, unsigned int& _value) const;
int getColorType(std::string & _line, bool _texCoordsAvailable) const;
//available options for reading
mutable Options options_;
//options that the user wants to read
mutable Options userOptions_;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the OFF reader
extern _OFFReader_ __OFFReaderInstance;
OPENMESHDLLEXPORT _OFFReader_& OFFReader();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,178 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a reader module for OFF files
//
//=============================================================================
#ifndef __OMREADER_HH__
#define __OMREADER_HH__
//=== INCLUDES ================================================================
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/OMFormat.hh>
#include <OpenMesh/Core/IO/IOManager.hh>
#include <OpenMesh/Core/IO/importer/BaseImporter.hh>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
// STD C++
#include <iosfwd>
#include <string>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//== IMPLEMENTATION ===========================================================
/**
Implementation of the OM format reader. This class is singleton'ed by
SingletonT to OMReader.
*/
class OPENMESHDLLEXPORT _OMReader_ : public BaseReader
{
public:
_OMReader_();
virtual ~_OMReader_() { }
std::string get_description() const { return "OpenMesh File Format"; }
std::string get_extensions() const { return "om"; }
std::string get_magic() const { return "OM"; }
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt );
//! Stream Reader for std::istream input in binary format
bool read(std::istream& _is,
BaseImporter& _bi,
Options& _opt );
virtual bool can_u_read(const std::string& _filename) const;
virtual bool can_u_read(std::istream& _is) const;
private:
bool supports( const OMFormat::uint8 version ) const;
bool read_ascii(std::istream& _is, BaseImporter& _bi, Options& _opt) const;
bool read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt) const;
typedef OMFormat::Header Header;
typedef OMFormat::Chunk::Header ChunkHeader;
typedef OMFormat::Chunk::PropertyName PropertyName;
// initialized/updated by read_binary*/read_ascii*
mutable size_t bytes_;
mutable Options fileOptions_;
mutable Header header_;
mutable ChunkHeader chunk_header_;
mutable PropertyName property_name_;
bool read_binary_vertex_chunk( std::istream &_is,
BaseImporter &_bi,
Options &_opt,
bool _swap) const;
bool read_binary_face_chunk( std::istream &_is,
BaseImporter &_bi,
Options &_opt,
bool _swap) const;
bool read_binary_edge_chunk( std::istream &_is,
BaseImporter &_bi,
Options &_opt,
bool _swap) const;
bool read_binary_halfedge_chunk( std::istream &_is,
BaseImporter &_bi,
Options &_opt,
bool _swap) const;
bool read_binary_mesh_chunk( std::istream &_is,
BaseImporter &_bi,
Options &_opt,
bool _swap) const;
size_t restore_binary_custom_data( std::istream& _is,
BaseProperty* _bp,
size_t _n_elem,
bool _swap) const;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the OM reader.
extern _OMReader_ __OMReaderInstance;
OPENMESHDLLEXPORT _OMReader_& OMReader();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,244 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a reader module for OFF files
//
//=============================================================================
#ifndef __PLYREADER_HH__
#define __PLYREADER_HH__
//=== INCLUDES ================================================================
#include <iosfwd>
#include <string>
#include <cstdio>
#include <vector>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//== FORWARDS =================================================================
class BaseImporter;
//== IMPLEMENTATION ===========================================================
/**
Implementation of the PLY format reader. This class is singleton'ed by
SingletonT to OFFReader. It can read custom properties, accessible via the name
of the custom properties. List properties has the type std::vector<Type>.
*/
class OPENMESHDLLEXPORT _PLYReader_ : public BaseReader
{
public:
_PLYReader_();
std::string get_description() const { return "PLY polygon file format"; }
std::string get_extensions() const { return "ply"; }
std::string get_magic() const { return "PLY"; }
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt);
bool read(std::istream& _is,
BaseImporter& _bi,
Options& _opt);
bool can_u_read(const std::string& _filename) const;
enum ValueType {
Unsupported,
ValueTypeINT8, ValueTypeCHAR,
ValueTypeUINT8, ValueTypeUCHAR,
ValueTypeINT16, ValueTypeSHORT,
ValueTypeUINT16, ValueTypeUSHORT,
ValueTypeINT32, ValueTypeINT,
ValueTypeUINT32, ValueTypeUINT,
ValueTypeFLOAT32, ValueTypeFLOAT,
ValueTypeFLOAT64, ValueTypeDOUBLE
};
private:
bool can_u_read(std::istream& _is) const;
bool read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const;
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const;
float readToFloatValue(ValueType _type , std::fstream& _in) const;
void readValue(ValueType _type , std::istream& _in, float& _value) const;
void readValue(ValueType _type , std::istream& _in, double& _value) const;
void readValue(ValueType _type , std::istream& _in, unsigned int& _value) const;
void readValue(ValueType _type , std::istream& _in, unsigned short& _value) const;
void readValue(ValueType _type , std::istream& _in, unsigned char& _value) const;
void readValue(ValueType _type , std::istream& _in, int& _value) const;
void readValue(ValueType _type , std::istream& _in, short& _value) const;
void readValue(ValueType _type , std::istream& _in, signed char& _value) const;
void readInteger(ValueType _type, std::istream& _in, int& _value) const;
void readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const;
/// Read unsupported properties in PLY file
void consume_input(std::istream& _in, int _count) const {
_in.read(reinterpret_cast<char*>(&buff[0]), _count);
}
mutable unsigned char buff[8];
/// Available per file options for reading
mutable Options options_;
/// Options that the user wants to read
mutable Options userOptions_;
mutable unsigned int vertexCount_;
mutable unsigned int faceCount_;
mutable uint vertexDimension_;
enum Property {
XCOORD,YCOORD,ZCOORD,
TEXX,TEXY,
COLORRED,COLORGREEN,COLORBLUE,COLORALPHA,
XNORM,YNORM,ZNORM, CUSTOM_PROP, VERTEX_INDICES,
UNSUPPORTED
};
/// Stores sizes of property types
mutable std::map<ValueType, int> scalar_size_;
// Number of vertex properties
struct PropertyInfo
{
Property property;
ValueType value;
std::string name;//for custom properties
ValueType listIndexType;//if type is unsupported, the poerty is not a list. otherwise, it the index type
PropertyInfo():property(UNSUPPORTED),value(Unsupported),name(""),listIndexType(Unsupported){}
PropertyInfo(Property _p, ValueType _v):property(_p),value(_v),name(""),listIndexType(Unsupported){}
PropertyInfo(Property _p, ValueType _v, const std::string& _n):property(_p),value(_v),name(_n),listIndexType(Unsupported){}
};
enum Element {
VERTEX,
FACE,
UNKNOWN
};
// Information on the elements
struct ElementInfo
{
Element element_;
std::string name_;
unsigned int count_;
std::vector< PropertyInfo > properties_;
};
mutable std::vector< ElementInfo > elements_;
template<typename T>
inline void read(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::TrueType /*_binary*/) const
{
readValue(_type, _in, _value);
}
template<typename T>
inline void read(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::FalseType /*_binary*/) const
{
_in >> _value;
}
//read and assign custom properties with the given type. Also creates property, if not exist
template<bool binary, typename T, typename Handle>
void readCreateCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const ValueType _valueType, const ValueType _listType) const;
template<bool binary, typename Handle>
void readCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const _PLYReader_::ValueType _valueType, const _PLYReader_::ValueType _listIndexType) const;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the PLY reader
extern _PLYReader_ __PLYReaderInstance;
OPENMESHDLLEXPORT _PLYReader_& PLYReader();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,151 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements an reader module for STL files
//
//=============================================================================
#ifndef __STLREADER_HH__
#define __STLREADER_HH__
//=== INCLUDES ================================================================
#include <stdio.h>
#include <string>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/reader/BaseReader.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//== FORWARDS =================================================================
class BaseImporter;
//== IMPLEMENTATION ===========================================================
/**
Implementation of the STL format reader. This class is singleton'ed by
SingletonT to STLReader.
*/
class OPENMESHDLLEXPORT _STLReader_ : public BaseReader
{
public:
// constructor
_STLReader_();
/// Destructor
virtual ~_STLReader_() {};
std::string get_description() const
{ return "Stereolithography Interface Format"; }
std::string get_extensions() const { return "stl stla stlb"; }
bool read(const std::string& _filename,
BaseImporter& _bi,
Options& _opt);
bool read(std::istream& _in,
BaseImporter& _bi,
Options& _opt);
/** Set the threshold to be used for considering two point to be equal.
Can be used to merge small gaps */
void set_epsilon(float _eps) { eps_=_eps; }
/// Returns the threshold to be used for considering two point to be equal.
float epsilon() const { return eps_; }
private:
enum STL_Type { STLA, STLB, NONE };
STL_Type check_stl_type(const std::string& _filename) const;
bool read_stla(const std::string& _filename, BaseImporter& _bi, Options& _opt) const;
bool read_stla(std::istream& _in, BaseImporter& _bi, Options& _opt) const;
bool read_stlb(const std::string& _filename, BaseImporter& _bi, Options& _opt) const;
bool read_stlb(std::istream& _in, BaseImporter& _bi, Options& _opt) const;
private:
float eps_;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the STL reader
extern _STLReader_ __STLReaderInstance;
OPENMESHDLLEXPORT _STLReader_& STLReader();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,155 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements the baseclass for IOManager writer modules
//
//=============================================================================
#ifndef __BASEWRITER_HH__
#define __BASEWRITER_HH__
//=== INCLUDES ================================================================
// STD C++
#include <iosfwd>
#include <string>
// OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/IO/Options.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
Base class for all writer modules. The module should register itself at
the IOManager by calling the register_module function.
*/
class OPENMESHDLLEXPORT BaseWriter
{
public:
typedef unsigned int Option;
/// Destructor
virtual ~BaseWriter() {};
/// Return short description of the supported file format.
virtual std::string get_description() const = 0;
/// Return file format's extension.
virtual std::string get_extensions() const = 0;
/** \brief Returns true if writer can write _filename (checks extension).
* _filename can also provide an extension without a name for a file e.g. _filename == "om" checks, if the writer can write the "om" extension
* @param _filename complete name of a file or just the extension
* @result true, if writer can write data with the given extension
*/
virtual bool can_u_write(const std::string& _filename) const;
/** Write to a file
* @param _filename write to file with the given filename
* @param _be BaseExporter, which specifies the data source
* @param _opt writing options
* @param _precision can be used to specify the precision of the floating point notation.
*/
virtual bool write(const std::string& _filename,
BaseExporter& _be,
Options _opt,
std::streamsize _precision = 6) const = 0;
/** Write to a std::ostream
* @param _os write to std::ostream
* @param _be BaseExporter, which specifies the data source
* @param _opt writing options
* @param _precision can be used to specify the precision of the floating point notation.
*/
virtual bool write(std::ostream& _os,
BaseExporter& _be,
Options _opt,
std::streamsize _precision = 6) const = 0;
/// Returns expected size of file if binary format is supported else 0.
virtual size_t binary_size(BaseExporter&, Options) const { return 0; }
protected:
bool check(BaseExporter& _be, Options _opt) const
{
return (_opt.check(Options::VertexNormal ) <= _be.has_vertex_normals())
&& (_opt.check(Options::VertexTexCoord)<= _be.has_vertex_texcoords())
&& (_opt.check(Options::VertexColor) <= _be.has_vertex_colors())
&& (_opt.check(Options::FaceNormal) <= _be.has_face_normals())
&& (_opt.check(Options::FaceColor) <= _be.has_face_colors());
}
};
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,136 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements an IOManager writer module for OBJ files
//
//=============================================================================
#ifndef __OBJWRITER_HH__
#define __OBJWRITER_HH__
//=== INCLUDES ================================================================
#include <string>
#include <fstream>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
This class defines the OBJ writer. This class is further singleton'ed
by SingletonT to OBJWriter.
*/
class OPENMESHDLLEXPORT _OBJWriter_ : public BaseWriter
{
public:
_OBJWriter_();
/// Destructor
virtual ~_OBJWriter_() {};
std::string get_description() const { return "Alias/Wavefront"; }
std::string get_extensions() const { return "obj"; }
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
size_t binary_size(BaseExporter&, Options) const { return 0; }
private:
mutable std::string path_;
mutable std::string objName_;
mutable std::vector< OpenMesh::Vec3f > material_;
mutable std::vector< OpenMesh::Vec4f > materialA_;
size_t getMaterial(OpenMesh::Vec3f _color) const;
size_t getMaterial(OpenMesh::Vec4f _color) const;
bool writeMaterial(std::ostream& _out, BaseExporter&, Options) const;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the OBJ writer
extern _OBJWriter_ __OBJWriterinstance;
OPENMESHDLLEXPORT _OBJWriter_& OBJWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,138 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a writer module for OFF files
//
//=============================================================================
#ifndef __OFFWRITER_HH__
#define __OFFWRITER_HH__
//=== INCLUDES ================================================================
#include <string>
#include <ostream>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
Implementation of the OFF format writer. This class is singleton'ed by
SingletonT to OFFWriter.
By passing Options to the write function you can manipulate the writing behavoir.
The following options can be set:
Binary
VertexNormal
VertexColor
VertexTexCoord
FaceColor
ColorAlpha
*/
class OPENMESHDLLEXPORT _OFFWriter_ : public BaseWriter
{
public:
_OFFWriter_();
virtual ~_OFFWriter_() {};
std::string get_description() const { return "no description"; }
std::string get_extensions() const { return "off"; }
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
size_t binary_size(BaseExporter& _be, Options _opt) const;
protected:
void writeValue(std::ostream& _out, int value) const;
void writeValue(std::ostream& _out, unsigned int value) const;
void writeValue(std::ostream& _out, float value) const;
bool write_ascii(std::ostream& _in, BaseExporter&, Options) const;
bool write_binary(std::ostream& _in, BaseExporter&, Options) const;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the OFF writer.
extern _OFFWriter_ __OFFWriterInstance;
OPENMESHDLLEXPORT _OFFWriter_& OFFWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,147 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a writer module for OM files
//
//=============================================================================
#ifndef __OMWRITER_HH__
#define __OMWRITER_HH__
//=== INCLUDES ================================================================
// STD C++
#include <iosfwd>
#include <string>
// OpenMesh
#include <OpenMesh/Core/IO/BinaryHelper.hh>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/OMFormat.hh>
#include <OpenMesh/Core/IO/IOManager.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== FORWARDS ================================================================
class BaseExporter;
//=== IMPLEMENTATION ==========================================================
/**
* Implementation of the OM format writer. This class is singleton'ed by
* SingletonT to OMWriter.
*/
class OPENMESHDLLEXPORT _OMWriter_ : public BaseWriter
{
public:
/// Constructor
_OMWriter_();
/// Destructor
virtual ~_OMWriter_() {};
std::string get_description() const
{ return "OpenMesh Format"; }
std::string get_extensions() const
{ return "om"; }
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
size_t binary_size(BaseExporter& _be, Options _opt) const;
protected:
static const OMFormat::uchar magic_[3];
static const OMFormat::uint8 version_;
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write_binary(std::ostream&, BaseExporter&, Options) const;
size_t store_binary_custom_chunk( std::ostream&, const BaseProperty&,
OMFormat::Chunk::Entity, bool) const;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the OM writer.
extern _OMWriter_ __OMWriterInstance;
OPENMESHDLLEXPORT _OMWriter_& OMWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,177 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a writer module for PLY files
//
//=============================================================================
#ifndef __PLYWRITER_HH__
#define __PLYWRITER_HH__
//=== INCLUDES ================================================================
#include <string>
#include <ostream>
#include <vector>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
Implementation of the PLY format writer. This class is singleton'ed by
SingletonT to PLYWriter.
currently supported options:
- VertexColors
- Binary
- Binary -> MSB
*/
class OPENMESHDLLEXPORT _PLYWriter_ : public BaseWriter
{
public:
_PLYWriter_();
/// Destructor
virtual ~_PLYWriter_() {};
std::string get_description() const { return "PLY polygon file format"; }
std::string get_extensions() const { return "ply"; }
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
size_t binary_size(BaseExporter& _be, Options _opt) const;
enum ValueType {
Unsupported = 0,
ValueTypeFLOAT32, ValueTypeFLOAT,
ValueTypeINT32, ValueTypeINT , ValueTypeUINT,
ValueTypeUCHAR, ValueTypeCHAR, ValueTypeUINT8,
ValueTypeUSHORT, ValueTypeSHORT,
ValueTypeDOUBLE
};
private:
mutable Options options_;
struct CustomProperty
{
ValueType type;
const BaseProperty* property;
CustomProperty(const BaseProperty* const _p):type(Unsupported),property(_p){}
};
const char* nameOfType_[12];
/// write custom persistant properties into the header for the current element, returns all properties, which were written sorted
std::vector<CustomProperty> writeCustomTypeHeader(std::ostream& _out, BaseKernel::const_prop_iterator _begin, BaseKernel::const_prop_iterator _end) const;
template<bool binary>
void write_customProp(std::ostream& _our, const CustomProperty& _prop, size_t _index) const;
template<typename T>
void writeProxy(ValueType _type, std::ostream& _out, T _value, OpenMesh::GenProg::TrueType /*_binary*/) const
{
writeValue(_type, _out, _value);
}
template<typename T>
void writeProxy(ValueType _type, std::ostream& _out, T _value, OpenMesh::GenProg::FalseType /*_binary*/) const
{
_out << " " << _value;
}
protected:
void writeValue(ValueType _type, std::ostream& _out, signed char value) const;
void writeValue(ValueType _type, std::ostream& _out, unsigned char value) const;
void writeValue(ValueType _type, std::ostream& _out, short value) const;
void writeValue(ValueType _type, std::ostream& _out, unsigned short value) const;
void writeValue(ValueType _type, std::ostream& _out, int value) const;
void writeValue(ValueType _type, std::ostream& _out, unsigned int value) const;
void writeValue(ValueType _type, std::ostream& _out, float value) const;
void writeValue(ValueType _type, std::ostream& _out, double value) const;
bool write_ascii(std::ostream& _out, BaseExporter&, Options) const;
bool write_binary(std::ostream& _out, BaseExporter&, Options) const;
/// write header into the stream _out. Returns custom properties (vertex and face) which are written into the header
void write_header(std::ostream& _out, BaseExporter& _be, Options& _opt, std::vector<CustomProperty>& _ovProps, std::vector<CustomProperty>& _ofProps) const;
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the PLY writer.
extern _PLYWriter_ __PLYWriterInstance;
OPENMESHDLLEXPORT _PLYWriter_& PLYWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,126 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// Implements a writer module for STL ascii files
//
//=============================================================================
// $Id: STLWriter.hh,v 1.2 2007-05-18 15:17:43 habbecke Exp $
#ifndef __STLWRITER_HH__
#define __STLWRITER_HH__
//=== INCLUDES ================================================================
// -------------------- STL
#include <iosfwd>
#include <string>
// -------------------- OpenMesh
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
/**
Implementation of the STL format writer. This class is singleton'ed by
SingletonT to STLWriter.
*/
class OPENMESHDLLEXPORT _STLWriter_ : public BaseWriter
{
public:
_STLWriter_();
/// Destructor
virtual ~_STLWriter_() {};
std::string get_description() const { return "Stereolithography Format"; }
std::string get_extensions() const { return "stl stla stlb"; }
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
size_t binary_size(BaseExporter&, Options) const;
private:
bool write_stla(const std::string&, BaseExporter&, Options) const;
bool write_stla(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write_stlb(const std::string&, BaseExporter&, Options) const;
bool write_stlb(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
};
//== TYPE DEFINITION ==========================================================
// Declare the single entity of STL writer.
extern _STLWriter_ __STLWriterInstance;
OPENMESHDLLEXPORT _STLWriter_& STLWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,52 @@
//=============================================================================
//
// Implements an IOManager writer module for VTK files
//
//=============================================================================
#ifndef __VTKWRITER_HH__
#define __VTKWRITER_HH__
//=== INCLUDES ================================================================
#include <string>
#include <iosfwd>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/SingletonT.hh>
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace IO {
//=== IMPLEMENTATION ==========================================================
class OPENMESHDLLEXPORT _VTKWriter_ : public BaseWriter
{
public:
_VTKWriter_();
std::string get_description() const { return "VTK"; }
std::string get_extensions() const { return "vtk"; }
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
size_t binary_size(BaseExporter&, Options) const { return 0; }
};
//== TYPE DEFINITION ==========================================================
/// Declare the single entity of the OBJ writer
extern _VTKWriter_ __VTKWriterinstance;
OPENMESHDLLEXPORT _VTKWriter_& VTKWriter();
//=============================================================================
} // namespace IO
} // namespace OpenMesh
//=============================================================================
#endif
//=============================================================================

View File

@ -0,0 +1,130 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef OPENMESH_ARRAY_ITEMS_HH
#define OPENMESH_ARRAY_ITEMS_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <OpenMesh/Core/Mesh/Handles.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/// Definition of mesh items for use in the ArrayKernel
struct ArrayItems
{
//------------------------------------------------------ internal vertex type
/// The vertex item
class Vertex
{
friend class ArrayKernel;
HalfedgeHandle halfedge_handle_;
};
//---------------------------------------------------- internal halfedge type
#ifndef DOXY_IGNORE_THIS
class Halfedge_without_prev
{
friend class ArrayKernel;
FaceHandle face_handle_;
VertexHandle vertex_handle_;
HalfedgeHandle next_halfedge_handle_;
};
#endif
#ifndef DOXY_IGNORE_THIS
class Halfedge_with_prev : public Halfedge_without_prev
{
friend class ArrayKernel;
HalfedgeHandle prev_halfedge_handle_;
};
#endif
//TODO: should be selected with config.h define
typedef Halfedge_with_prev Halfedge;
typedef GenProg::Bool2Type<true> HasPrevHalfedge;
//-------------------------------------------------------- internal edge type
#ifndef DOXY_IGNORE_THIS
class Edge
{
friend class ArrayKernel;
Halfedge halfedges_[2];
};
#endif
//-------------------------------------------------------- internal face type
#ifndef DOXY_IGNORE_THIS
class Face
{
friend class ArrayKernel;
HalfedgeHandle halfedge_handle_;
};
};
#endif
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_ITEMS_HH defined
//=============================================================================

View File

@ -0,0 +1,915 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS ArrayKernel
//
//=============================================================================
#ifndef OPENMESH_ARRAY_KERNEL_HH
#define OPENMESH_ARRAY_KERNEL_HH
//== INCLUDES =================================================================
#include <vector>
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <OpenMesh/Core/Mesh/ArrayItems.hh>
#include <OpenMesh/Core/Mesh/BaseKernel.hh>
#include <OpenMesh/Core/Mesh/Status.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/** \ingroup mesh_kernels_group
Mesh kernel using arrays for mesh item storage.
This mesh kernel uses the std::vector as container to store the
mesh items. Therefore all handle types are internally represented
by integers. To get the index from a handle use the handle's \c
idx() method.
\note For a description of the minimal kernel interface see
OpenMesh::Mesh::BaseKernel.
\note You do not have to use this class directly, use the predefined
mesh-kernel combinations in \ref mesh_types_group.
\see OpenMesh::Concepts::KernelT, \ref mesh_type
*/
class OPENMESHDLLEXPORT ArrayKernel : public BaseKernel, public ArrayItems
{
public:
// handles
typedef OpenMesh::VertexHandle VertexHandle;
typedef OpenMesh::HalfedgeHandle HalfedgeHandle;
typedef OpenMesh::EdgeHandle EdgeHandle;
typedef OpenMesh::FaceHandle FaceHandle;
typedef Attributes::StatusInfo StatusInfo;
typedef VPropHandleT<StatusInfo> VertexStatusPropertyHandle;
typedef HPropHandleT<StatusInfo> HalfedgeStatusPropertyHandle;
typedef EPropHandleT<StatusInfo> EdgeStatusPropertyHandle;
typedef FPropHandleT<StatusInfo> FaceStatusPropertyHandle;
public:
// --- constructor/destructor ---
ArrayKernel();
virtual ~ArrayKernel();
/** ArrayKernel uses the default copy constructor and assignment operator, which means
that the connectivity and all properties are copied, including reference
counters, allocated bit status masks, etc.. In contrast assign_connectivity
copies only the connectivity, i.e. vertices, edges, faces and their status fields.
NOTE: The geometry (the points property) is NOT copied. Poly/TriConnectivity
override(and hide) that function to provide connectivity consistence.*/
void assign_connectivity(const ArrayKernel& _other);
// --- handle -> item ---
VertexHandle handle(const Vertex& _v) const;
HalfedgeHandle handle(const Halfedge& _he) const;
EdgeHandle handle(const Edge& _e) const;
FaceHandle handle(const Face& _f) const;
///checks handle validity - useful for debugging
bool is_valid_handle(VertexHandle _vh) const;
///checks handle validity - useful for debugging
bool is_valid_handle(HalfedgeHandle _heh) const;
///checks handle validity - useful for debugging
bool is_valid_handle(EdgeHandle _eh) const;
///checks handle validity - useful for debugging
bool is_valid_handle(FaceHandle _fh) const;
// --- item -> handle ---
const Vertex& vertex(VertexHandle _vh) const
{
assert(is_valid_handle(_vh));
return vertices_[_vh.idx()];
}
Vertex& vertex(VertexHandle _vh)
{
assert(is_valid_handle(_vh));
return vertices_[_vh.idx()];
}
const Halfedge& halfedge(HalfedgeHandle _heh) const
{
assert(is_valid_handle(_heh));
return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
}
Halfedge& halfedge(HalfedgeHandle _heh)
{
assert(is_valid_handle(_heh));
return edges_[_heh.idx() >> 1].halfedges_[_heh.idx() & 1];
}
const Edge& edge(EdgeHandle _eh) const
{
assert(is_valid_handle(_eh));
return edges_[_eh.idx()];
}
Edge& edge(EdgeHandle _eh)
{
assert(is_valid_handle(_eh));
return edges_[_eh.idx()];
}
const Face& face(FaceHandle _fh) const
{
assert(is_valid_handle(_fh));
return faces_[_fh.idx()];
}
Face& face(FaceHandle _fh)
{
assert(is_valid_handle(_fh));
return faces_[_fh.idx()];
}
// --- get i'th items ---
VertexHandle vertex_handle(unsigned int _i) const
{ return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
HalfedgeHandle halfedge_handle(unsigned int _i) const
{
return (_i < n_halfedges()) ?
halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
}
EdgeHandle edge_handle(unsigned int _i) const
{ return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
FaceHandle face_handle(unsigned int _i) const
{ return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
public:
/**
* \brief Add a new vertex.
*
* If you are rebuilding a mesh that you previously erased using clean() or
* clean_keep_reservation() you probably want to use new_vertex_dirty()
* instead.
*
* \sa new_vertex_dirty()
*/
inline VertexHandle new_vertex()
{
vertices_.push_back(Vertex());
vprops_resize(n_vertices());//TODO:should it be push_back()?
return handle(vertices_.back());
}
/**
* Same as new_vertex() but uses PropertyContainer::resize_if_smaller() to
* resize the vertex property container.
*
* If you are rebuilding a mesh that you erased with clean() or
* clean_keep_reservation() using this method instead of new_vertex() saves
* reallocation and reinitialization of property memory.
*
* \sa new_vertex()
*/
inline VertexHandle new_vertex_dirty()
{
vertices_.push_back(Vertex());
vprops_resize_if_smaller(n_vertices());//TODO:should it be push_back()?
return handle(vertices_.back());
}
inline HalfedgeHandle new_edge(VertexHandle _start_vh, VertexHandle _end_vh)
{
// assert(_start_vh != _end_vh);
edges_.push_back(Edge());
eprops_resize(n_edges());//TODO:should it be push_back()?
hprops_resize(n_halfedges());//TODO:should it be push_back()?
EdgeHandle eh(handle(edges_.back()));
HalfedgeHandle heh0(halfedge_handle(eh, 0));
HalfedgeHandle heh1(halfedge_handle(eh, 1));
set_vertex_handle(heh0, _end_vh);
set_vertex_handle(heh1, _start_vh);
return heh0;
}
inline FaceHandle new_face()
{
faces_.push_back(Face());
fprops_resize(n_faces());
return handle(faces_.back());
}
inline FaceHandle new_face(const Face& _f)
{
faces_.push_back(_f);
fprops_resize(n_faces());
return handle(faces_.back());
}
public:
// --- resize/reserve ---
void resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces );
void reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces );
// --- deletion ---
/** \brief garbage collection
*
* Usually if you delete primitives in OpenMesh, they are only flagged as deleted.
* Only when you call garbage collection, they will be actually removed.
*
* \note Garbage collection invalidates all handles. If you need to keep track of
* a set of handles, you can pass them to the second garbage collection
* function, which will update a vector of handles.
* See also \ref deletedElements.
*
* @param _v Remove deleted vertices?
* @param _e Remove deleted edges?
* @param _f Remove deleted faces?
*
*/
void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
/** \brief garbage collection with handle tracking
*
* Usually if you delete primitives in OpenMesh, they are only flagged as deleted.
* Only when you call garbage collection, they will be actually removed.
*
* \note Garbage collection invalidates all handles. If you need to keep track of
* a set of handles, you can pass them to this function. The handles that the
* given pointers point to are updated in place.
* See also \ref deletedElements.
*
* @param vh_to_update Pointers to vertex handles that should get updated
* @param hh_to_update Pointers to halfedge handles that should get updated
* @param fh_to_update Pointers to face handles that should get updated
* @param _v Remove deleted vertices?
* @param _e Remove deleted edges?
* @param _f Remove deleted faces?
*/
template<typename std_API_Container_VHandlePointer,
typename std_API_Container_HHandlePointer,
typename std_API_Container_FHandlePointer>
void garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
std_API_Container_HHandlePointer& hh_to_update,
std_API_Container_FHandlePointer& fh_to_update,
bool _v=true, bool _e=true, bool _f=true);
/// \brief Does the same as clean() and in addition erases all properties.
void clear();
/** \brief Remove all vertices, edges and faces and deallocates their memory.
*
* In contrast to clear() this method does neither erases the properties
* nor clears the property vectors. Depending on how you add any new entities
* to the mesh after calling this method, your properties will be initialized
* with old values.
*
* \sa clean_keep_reservation()
*/
void clean();
/** \brief Remove all vertices, edges and faces but keep memory allocated.
*
* This method behaves like clean() (also regarding the properties) but
* leaves the memory used for vertex, edge and face storage allocated. This
* leads to no reduction in memory consumption but allows for faster
* performance when rebuilding the mesh.
*/
void clean_keep_reservation();
// --- number of items ---
size_t n_vertices() const { return vertices_.size(); }
size_t n_halfedges() const { return 2*edges_.size(); }
size_t n_edges() const { return edges_.size(); }
size_t n_faces() const { return faces_.size(); }
bool vertices_empty() const { return vertices_.empty(); }
bool halfedges_empty() const { return edges_.empty(); }
bool edges_empty() const { return edges_.empty(); }
bool faces_empty() const { return faces_.empty(); }
// --- vertex connectivity ---
HalfedgeHandle halfedge_handle(VertexHandle _vh) const
{ return vertex(_vh).halfedge_handle_; }
void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh)
{
// assert(is_valid_handle(_heh));
vertex(_vh).halfedge_handle_ = _heh;
}
bool is_isolated(VertexHandle _vh) const
{ return !halfedge_handle(_vh).is_valid(); }
void set_isolated(VertexHandle _vh)
{ vertex(_vh).halfedge_handle_.invalidate(); }
unsigned int delete_isolated_vertices();
// --- halfedge connectivity ---
VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
{ return halfedge(_heh).vertex_handle_; }
VertexHandle from_vertex_handle(HalfedgeHandle _heh) const
{ return to_vertex_handle(opposite_halfedge_handle(_heh)); }
void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh)
{
// assert(is_valid_handle(_vh));
halfedge(_heh).vertex_handle_ = _vh;
}
FaceHandle face_handle(HalfedgeHandle _heh) const
{ return halfedge(_heh).face_handle_; }
void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh)
{
// assert(is_valid_handle(_fh));
halfedge(_heh).face_handle_ = _fh;
}
void set_boundary(HalfedgeHandle _heh)
{ halfedge(_heh).face_handle_.invalidate(); }
/// Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
bool is_boundary(HalfedgeHandle _heh) const
{ return !face_handle(_heh).is_valid(); }
HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const
{ return halfedge(_heh).next_halfedge_handle_; }
void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh)
{
assert(is_valid_handle(_nheh));
// assert(to_vertex_handle(_heh) == from_vertex_handle(_nheh));
halfedge(_heh).next_halfedge_handle_ = _nheh;
set_prev_halfedge_handle(_nheh, _heh);
}
void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh)
{
assert(is_valid_handle(_pheh));
set_prev_halfedge_handle(_heh, _pheh, HasPrevHalfedge());
}
void set_prev_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _pheh,
GenProg::TrueType)
{ halfedge(_heh).prev_halfedge_handle_ = _pheh; }
void set_prev_halfedge_handle(HalfedgeHandle /* _heh */, HalfedgeHandle /* _pheh */,
GenProg::FalseType)
{}
HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const
{ return prev_halfedge_handle(_heh, HasPrevHalfedge() ); }
HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::TrueType) const
{ return halfedge(_heh).prev_halfedge_handle_; }
HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh, GenProg::FalseType) const
{
if (is_boundary(_heh))
{//iterating around the vertex should be faster than iterating the boundary
HalfedgeHandle curr_heh(opposite_halfedge_handle(_heh));
HalfedgeHandle next_heh(next_halfedge_handle(curr_heh));
do
{
curr_heh = opposite_halfedge_handle(next_heh);
next_heh = next_halfedge_handle(curr_heh);
}
while (next_heh != _heh);
return curr_heh;
}
else
{
HalfedgeHandle heh(_heh);
HalfedgeHandle next_heh(next_halfedge_handle(heh));
while (next_heh != _heh) {
heh = next_heh;
next_heh = next_halfedge_handle(next_heh);
}
return heh;
}
}
HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
{ return HalfedgeHandle(_heh.idx() ^ 1); }
HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const
{ return opposite_halfedge_handle(prev_halfedge_handle(_heh)); }
HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const
{ return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
// --- edge connectivity ---
static HalfedgeHandle s_halfedge_handle(EdgeHandle _eh, unsigned int _i)
{
assert(_i<=1);
return HalfedgeHandle((_eh.idx() << 1) + _i);
}
static EdgeHandle s_edge_handle(HalfedgeHandle _heh)
{ return EdgeHandle(_heh.idx() >> 1); }
HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
{
return s_halfedge_handle(_eh, _i);
}
EdgeHandle edge_handle(HalfedgeHandle _heh) const
{ return s_edge_handle(_heh); }
// --- face connectivity ---
HalfedgeHandle halfedge_handle(FaceHandle _fh) const
{ return face(_fh).halfedge_handle_; }
void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh)
{
// assert(is_valid_handle(_heh));
face(_fh).halfedge_handle_ = _heh;
}
/// Status Query API
//------------------------------------------------------------ vertex status
const StatusInfo& status(VertexHandle _vh) const
{ return property(vertex_status_, _vh); }
StatusInfo& status(VertexHandle _vh)
{ return property(vertex_status_, _vh); }
/**
* Reinitializes the status of all vertices using the StatusInfo default
* constructor, i.e. all flags will be set to false.
*/
void reset_status() {
PropertyT<StatusInfo> &status_prop = property(vertex_status_);
PropertyT<StatusInfo>::vector_type &sprop_v = status_prop.data_vector();
std::fill(sprop_v.begin(), sprop_v.begin() + n_vertices(), StatusInfo());
}
//----------------------------------------------------------- halfedge status
const StatusInfo& status(HalfedgeHandle _hh) const
{ return property(halfedge_status_, _hh); }
StatusInfo& status(HalfedgeHandle _hh)
{ return property(halfedge_status_, _hh); }
//--------------------------------------------------------------- edge status
const StatusInfo& status(EdgeHandle _eh) const
{ return property(edge_status_, _eh); }
StatusInfo& status(EdgeHandle _eh)
{ return property(edge_status_, _eh); }
//--------------------------------------------------------------- face status
const StatusInfo& status(FaceHandle _fh) const
{ return property(face_status_, _fh); }
StatusInfo& status(FaceHandle _fh)
{ return property(face_status_, _fh); }
inline bool has_vertex_status() const
{ return vertex_status_.is_valid(); }
inline bool has_halfedge_status() const
{ return halfedge_status_.is_valid(); }
inline bool has_edge_status() const
{ return edge_status_.is_valid(); }
inline bool has_face_status() const
{ return face_status_.is_valid(); }
inline VertexStatusPropertyHandle vertex_status_pph() const
{ return vertex_status_; }
inline HalfedgeStatusPropertyHandle halfedge_status_pph() const
{ return halfedge_status_; }
inline EdgeStatusPropertyHandle edge_status_pph() const
{ return edge_status_; }
inline FaceStatusPropertyHandle face_status_pph() const
{ return face_status_; }
/// status property by handle
inline VertexStatusPropertyHandle status_pph(VertexHandle /*_hnd*/) const
{ return vertex_status_pph(); }
inline HalfedgeStatusPropertyHandle status_pph(HalfedgeHandle /*_hnd*/) const
{ return halfedge_status_pph(); }
inline EdgeStatusPropertyHandle status_pph(EdgeHandle /*_hnd*/) const
{ return edge_status_pph(); }
inline FaceStatusPropertyHandle status_pph(FaceHandle /*_hnd*/) const
{ return face_status_pph(); }
/// Status Request API
void request_vertex_status()
{
if (!refcount_vstatus_++)
add_property( vertex_status_, "v:status" );
}
void request_halfedge_status()
{
if (!refcount_hstatus_++)
add_property( halfedge_status_, "h:status" );
}
void request_edge_status()
{
if (!refcount_estatus_++)
add_property( edge_status_, "e:status" );
}
void request_face_status()
{
if (!refcount_fstatus_++)
add_property( face_status_, "f:status" );
}
/// Status Release API
void release_vertex_status()
{
if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
remove_property(vertex_status_);
}
void release_halfedge_status()
{
if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
remove_property(halfedge_status_);
}
void release_edge_status()
{
if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
remove_property(edge_status_);
}
void release_face_status()
{
if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
remove_property(face_status_);
}
/// --- StatusSet API ---
/*!
Implements a set of connectivity entities (vertex, edge, face, halfedge)
using the available bits in the corresponding mesh status field.
Status-based sets are much faster than std::set<> and equivalent
in performance to std::vector<bool>, but much more convenient.
*/
template <class HandleT>
class StatusSetT
{
public:
typedef HandleT Handle;
protected:
ArrayKernel& kernel_;
public:
const unsigned int bit_mask_;
public:
StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
: kernel_(_kernel), bit_mask_(_bit_mask)
{}
~StatusSetT()
{}
inline bool is_in(Handle _hnd) const
{ return kernel_.status(_hnd).is_bit_set(bit_mask_); }
inline void insert(Handle _hnd)
{ kernel_.status(_hnd).set_bit(bit_mask_); }
inline void erase(Handle _hnd)
{ kernel_.status(_hnd).unset_bit(bit_mask_); }
//! Note: 0(n) complexity
size_t size() const
{
const int n = kernel_.status_pph(Handle()).is_valid() ?
(int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
size_t sz = 0;
for (int i = 0; i < n; ++i)
sz += (size_t)is_in(Handle(i));
return sz;
}
//! Note: O(n) complexity
void clear()
{
const int n = kernel_.status_pph(Handle()).is_valid() ?
(int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
for (int i = 0; i < n; ++i)
erase(Handle(i));
}
};
friend class StatusSetT<VertexHandle>;
friend class StatusSetT<EdgeHandle>;
friend class StatusSetT<FaceHandle>;
friend class StatusSetT<HalfedgeHandle>;
//! AutoStatusSetT: A status set that automatically picks a status bit
template <class HandleT>
class AutoStatusSetT : public StatusSetT<HandleT>
{
private:
typedef HandleT Handle;
typedef StatusSetT<Handle> Base;
public:
AutoStatusSetT(ArrayKernel& _kernel)
: StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
{ /*assert(size() == 0);*/ } //the set should be empty on creation
~AutoStatusSetT()
{
//assert(size() == 0);//the set should be empty on leave?
Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
}
};
friend class AutoStatusSetT<VertexHandle>;
friend class AutoStatusSetT<EdgeHandle>;
friend class AutoStatusSetT<FaceHandle>;
friend class AutoStatusSetT<HalfedgeHandle>;
typedef AutoStatusSetT<VertexHandle> VertexStatusSet;
typedef AutoStatusSetT<EdgeHandle> EdgeStatusSet;
typedef AutoStatusSetT<FaceHandle> FaceStatusSet;
typedef AutoStatusSetT<HalfedgeHandle> HalfedgeStatusSet;
//! ExtStatusSet: A status set augmented with an array
template <class HandleT>
class ExtStatusSetT : public AutoStatusSetT<HandleT>
{
public:
typedef HandleT Handle;
typedef AutoStatusSetT<Handle> Base;
protected:
typedef std::vector<Handle> HandleContainer;
HandleContainer handles_;
public:
typedef typename HandleContainer::iterator
iterator;
typedef typename HandleContainer::const_iterator
const_iterator;
public:
ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
: Base(_kernel)
{ handles_.reserve(_capacity_hint); }
~ExtStatusSetT()
{ clear(); }
// Complexity: O(1)
inline void insert(Handle _hnd)
{
if (!is_in(_hnd))
{
Base::insert(_hnd);
handles_.push_back(_hnd);
}
}
//! Complexity: O(k), (k - number of the elements in the set)
inline void erase(Handle _hnd)
{
if (is_in(_hnd))
{
iterator it = std::find(begin(), end(), _hnd);
erase(it);
}
}
//! Complexity: O(1)
inline void erase(iterator _it)
{
assert(_it != end() && is_in(*_it));
Base::erase(*_it);
*_it = handles_.back();
_it.pop_back();
}
inline void clear()
{
for (iterator it = begin(); it != end(); ++it)
{
assert(is_in(*it));
Base::erase(*it);
}
handles_.clear();
}
/// Complexity: 0(1)
inline unsigned int size() const
{ return handles_.size(); }
inline bool empty() const
{ return handles_.empty(); }
//Vector API
inline iterator begin()
{ return handles_.begin(); }
inline const_iterator begin() const
{ return handles_.begin(); }
inline iterator end()
{ return handles_.end(); }
inline const_iterator end() const
{ return handles_.end(); }
inline Handle& front()
{ return handles_.front(); }
inline const Handle& front() const
{ return handles_.front(); }
inline Handle& back()
{ return handles_.back(); }
inline const Handle& back() const
{ return handles_.back(); }
};
typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
private:
// iterators
typedef std::vector<Vertex> VertexContainer;
typedef std::vector<Edge> EdgeContainer;
typedef std::vector<Face> FaceContainer;
typedef VertexContainer::iterator KernelVertexIter;
typedef VertexContainer::const_iterator KernelConstVertexIter;
typedef EdgeContainer::iterator KernelEdgeIter;
typedef EdgeContainer::const_iterator KernelConstEdgeIter;
typedef FaceContainer::iterator KernelFaceIter;
typedef FaceContainer::const_iterator KernelConstFaceIter;
typedef std::vector<unsigned int> BitMaskContainer;
KernelVertexIter vertices_begin() { return vertices_.begin(); }
KernelConstVertexIter vertices_begin() const { return vertices_.begin(); }
KernelVertexIter vertices_end() { return vertices_.end(); }
KernelConstVertexIter vertices_end() const { return vertices_.end(); }
KernelEdgeIter edges_begin() { return edges_.begin(); }
KernelConstEdgeIter edges_begin() const { return edges_.begin(); }
KernelEdgeIter edges_end() { return edges_.end(); }
KernelConstEdgeIter edges_end() const { return edges_.end(); }
KernelFaceIter faces_begin() { return faces_.begin(); }
KernelConstFaceIter faces_begin() const { return faces_.begin(); }
KernelFaceIter faces_end() { return faces_.end(); }
KernelConstFaceIter faces_end() const { return faces_.end(); }
/// bit mask container by handle
inline BitMaskContainer& bit_masks(VertexHandle /*_dummy_hnd*/)
{ return vertex_bit_masks_; }
inline BitMaskContainer& bit_masks(EdgeHandle /*_dummy_hnd*/)
{ return edge_bit_masks_; }
inline BitMaskContainer& bit_masks(FaceHandle /*_dummy_hnd*/)
{ return face_bit_masks_; }
inline BitMaskContainer& bit_masks(HalfedgeHandle /*_dummy_hnd*/)
{ return halfedge_bit_masks_; }
template <class Handle>
unsigned int pop_bit_mask(Handle _hnd)
{
assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
unsigned int bit_mask = bit_masks(_hnd).back();
bit_masks(_hnd).pop_back();
return bit_mask;
}
template <class Handle>
void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
{
assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
bit_masks(_hnd).end());//this mask should be not already used
bit_masks(_hnd).push_back(_bit_mask);
}
void init_bit_masks(BitMaskContainer& _bmc);
void init_bit_masks();
protected:
VertexStatusPropertyHandle vertex_status_;
HalfedgeStatusPropertyHandle halfedge_status_;
EdgeStatusPropertyHandle edge_status_;
FaceStatusPropertyHandle face_status_;
unsigned int refcount_vstatus_;
unsigned int refcount_hstatus_;
unsigned int refcount_estatus_;
unsigned int refcount_fstatus_;
private:
VertexContainer vertices_;
EdgeContainer edges_;
FaceContainer faces_;
BitMaskContainer halfedge_bit_masks_;
BitMaskContainer edge_bit_masks_;
BitMaskContainer vertex_bit_masks_;
BitMaskContainer face_bit_masks_;
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
# define OPENMESH_ARRAY_KERNEL_TEMPLATES
# include "ArrayKernelT.cc"
#endif
//=============================================================================
#endif // OPENMESH_ARRAY_KERNEL_HH defined
//=============================================================================

View File

@ -0,0 +1,315 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision: 362 $ *
* $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ *
* *
\*===========================================================================*/
#define OPENMESH_ARRAY_KERNEL_C
//== INCLUDES =================================================================
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh
{
//== IMPLEMENTATION ==========================================================
template<typename std_API_Container_VHandlePointer,
typename std_API_Container_HHandlePointer,
typename std_API_Container_FHandlePointer>
void ArrayKernel::garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
std_API_Container_HHandlePointer& hh_to_update,
std_API_Container_FHandlePointer& fh_to_update,
bool _v, bool _e, bool _f)
{
#ifdef DEBUG
#ifndef OM_GARBAGE_NO_STATUS_WARNING
if ( !this->has_vertex_status() )
omerr() << "garbage_collection: No vertex status available. You can request it: mesh.request_vertex_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
if ( !this->has_edge_status() )
omerr() << "garbage_collection: No edge status available. You can request it: mesh.request_edge_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
if ( !this->has_face_status() )
omerr() << "garbage_collection: No face status available. You can request it: mesh.request_face_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
#endif
#endif
const bool track_vhandles = ( !vh_to_update.empty() );
const bool track_hhandles = ( !hh_to_update.empty() );
const bool track_fhandles = ( !fh_to_update.empty() );
int i, i0, i1;
int nV = int(n_vertices());
int nE = int(n_edges());
int nH = int(2*n_edges());
int nF = (int(n_faces()));
std::vector<VertexHandle> vh_map;
std::vector<HalfedgeHandle> hh_map;
std::vector<FaceHandle> fh_map;
std::map <int, int> vertex_inverse_map;
std::map <int, int> halfedge_inverse_map;
std::map <int, int> face_inverse_map;
// setup handle mapping:
vh_map.reserve(nV);
for (i=0; i<nV; ++i) vh_map.push_back(VertexHandle(i));
hh_map.reserve(nH);
for (i=0; i<nH; ++i) hh_map.push_back(HalfedgeHandle(i));
fh_map.reserve(nF);
for (i=0; i<nF; ++i) fh_map.push_back(FaceHandle(i));
// remove deleted vertices
if (_v && n_vertices() > 0 && this->has_vertex_status() )
{
i0=0; i1=nV-1;
while (1)
{
// find 1st deleted and last un-deleted
while (!status(VertexHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(VertexHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
// If we keep track of the vertex handles for updates,
// we need to have the opposite direction
if ( track_vhandles ) {
vertex_inverse_map[i1] = i0;
vertex_inverse_map[i0] = -1;
}
// swap
std::swap(vertices_[i0], vertices_[i1]);
std::swap(vh_map[i0], vh_map[i1]);
vprops_swap(i0, i1);
};
vertices_.resize(status(VertexHandle(i0)).deleted() ? i0 : i0+1);
vprops_resize(n_vertices());
}
// remove deleted edges
if (_e && n_edges() > 0 && this->has_edge_status() )
{
i0=0; i1=nE-1;
while (1)
{
// find 1st deleted and last un-deleted
while (!status(EdgeHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(EdgeHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
// If we keep track of the vertex handles for updates,
// we need to have the opposite direction
if ( track_hhandles ) {
halfedge_inverse_map[2*i1] = 2 * i0;
halfedge_inverse_map[2*i0] = -1;
halfedge_inverse_map[2*i1 + 1] = 2 * i0 + 1;
halfedge_inverse_map[2*i0 + 1] = -1;
}
// swap
std::swap(edges_[i0], edges_[i1]);
std::swap(hh_map[2*i0], hh_map[2*i1]);
std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
eprops_swap(i0, i1);
hprops_swap(2*i0, 2*i1);
hprops_swap(2*i0+1, 2*i1+1);
};
edges_.resize(status(EdgeHandle(i0)).deleted() ? i0 : i0+1);
eprops_resize(n_edges());
hprops_resize(n_halfedges());
}
// remove deleted faces
if (_f && n_faces() > 0 && this->has_face_status() )
{
i0=0; i1=nF-1;
while (1)
{
// find 1st deleted and last un-deleted
while (!status(FaceHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(FaceHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
// If we keep track of the face handles for updates,
// we need to have the opposite direction
if ( track_fhandles ) {
face_inverse_map[i1] = i0;
face_inverse_map[i0] = -1;
}
// swap
std::swap(faces_[i0], faces_[i1]);
std::swap(fh_map[i0], fh_map[i1]);
fprops_swap(i0, i1);
};
faces_.resize(status(FaceHandle(i0)).deleted() ? i0 : i0+1);
fprops_resize(n_faces());
}
// update handles of vertices
if (_e)
{
KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
VertexHandle vh;
for (; v_it!=v_end; ++v_it)
{
vh = handle(*v_it);
if (!is_isolated(vh))
{
set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
}
}
}
HalfedgeHandle hh;
// update handles of halfedges
for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
{//in the first pass update the (half)edges vertices
hh = halfedge_handle(handle(*e_it), 0);
set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
hh = halfedge_handle(handle(*e_it), 1);
set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
}
for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
{//in the second pass update the connectivity of the (half)edges
hh = halfedge_handle(handle(*e_it), 0);
set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
if (!is_boundary(hh))
{
set_face_handle(hh, fh_map[face_handle(hh).idx()]);
}
hh = halfedge_handle(handle(*e_it), 1);
set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
if (!is_boundary(hh))
{
set_face_handle(hh, fh_map[face_handle(hh).idx()]);
}
}
// update handles of faces
if (_e)
{
KernelFaceIter f_it(faces_begin()), f_end(faces_end());
FaceHandle fh;
for (; f_it!=f_end; ++f_it)
{
fh = handle(*f_it);
set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
}
}
const int vertexCount = int(vertices_.size());
const int halfedgeCount = int(edges_.size() * 2);
const int faceCount = int(faces_.size());
// Update the vertex handles in the vertex handle vector
typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end());
for(; v_it != v_it_end; ++v_it)
{
// Only changed vertices need to be considered
if ( (*v_it)->idx() != vh_map[(*v_it)->idx()].idx() ) {
*(*v_it) = VertexHandle(vertex_inverse_map[(*v_it)->idx()]);
// Vertices above the vertex count have to be already mapped, or they are invalid now!
} else if ( ((*v_it)->idx() >= vertexCount) && (vertex_inverse_map.find((*v_it)->idx()) == vertex_inverse_map.end()) ) {
(*v_it)->invalidate();
}
}
// Update the halfedge handles in the halfedge handle vector
typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end());
for(; hh_it != hh_it_end; ++hh_it)
{
// Only changed faces need to be considered
if ( (*hh_it)->idx() != hh_map[(*hh_it)->idx()].idx() ) {
*(*hh_it) = HalfedgeHandle(halfedge_inverse_map[(*hh_it)->idx()]);
// Vertices above the face count have to be already mapped, or they are invalid now!
} else if ( ((*hh_it)->idx() >= halfedgeCount) && (halfedge_inverse_map.find((*hh_it)->idx()) == halfedge_inverse_map.end()) ) {
(*hh_it)->invalidate();
}
}
// Update the face handles in the face handle vector
typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end());
for(; fh_it != fh_it_end; ++fh_it)
{
// Only changed faces need to be considered
if ( (*fh_it)->idx() != fh_map[(*fh_it)->idx()].idx() ) {
*(*fh_it) = FaceHandle(face_inverse_map[(*fh_it)->idx()]);
// Vertices above the face count have to be already mapped, or they are invalid now!
} else if ( ((*fh_it)->idx() >= faceCount) && (face_inverse_map.find((*fh_it)->idx()) == face_inverse_map.end()) ) {
(*fh_it)->invalidate();
}
}
}
}

View File

@ -0,0 +1,782 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef OPENMESH_ATTRIBKERNEL_HH
#define OPENMESH_ATTRIBKERNEL_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/Mesh/Attributes.hh>
#include <OpenMesh/Core/Utils/GenProg.hh>
#include <OpenMesh/Core/Utils/vector_traits.hh>
#include <vector>
#include <algorithm>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/** \class AttribKernelT AttribKernelT.hh <OpenMesh/Mesh/AttribKernelT.hh>
The attribute kernel adds all standard properties to the kernel. Therefore
the functions/types defined here provide a subset of the kernel
interface as described in Concepts::KernelT.
\see Concepts::KernelT
*/
template <class MeshItems, class Connectivity>
class AttribKernelT : public Connectivity
{
public:
//---------------------------------------------------------------- item types
typedef MeshItems MeshItemsT;
typedef Connectivity ConnectivityT;
typedef typename Connectivity::Vertex Vertex;
typedef typename Connectivity::Halfedge Halfedge;
typedef typename Connectivity::Edge Edge;
typedef typename Connectivity::Face Face;
typedef typename MeshItems::Point Point;
typedef typename MeshItems::Normal Normal;
typedef typename MeshItems::Color Color;
typedef typename MeshItems::TexCoord1D TexCoord1D;
typedef typename MeshItems::TexCoord2D TexCoord2D;
typedef typename MeshItems::TexCoord3D TexCoord3D;
typedef typename MeshItems::Scalar Scalar;
typedef typename MeshItems::TextureIndex TextureIndex;
typedef typename MeshItems::VertexData VertexData;
typedef typename MeshItems::HalfedgeData HalfedgeData;
typedef typename MeshItems::EdgeData EdgeData;
typedef typename MeshItems::FaceData FaceData;
typedef AttribKernelT<MeshItems,Connectivity> AttribKernel;
enum Attribs {
VAttribs = MeshItems::VAttribs,
HAttribs = MeshItems::HAttribs,
EAttribs = MeshItems::EAttribs,
FAttribs = MeshItems::FAttribs
};
typedef VPropHandleT<VertexData> DataVPropHandle;
typedef HPropHandleT<HalfedgeData> DataHPropHandle;
typedef EPropHandleT<EdgeData> DataEPropHandle;
typedef FPropHandleT<FaceData> DataFPropHandle;
public:
//-------------------------------------------------- constructor / destructor
AttribKernelT()
: refcount_vnormals_(0),
refcount_vcolors_(0),
refcount_vtexcoords1D_(0),
refcount_vtexcoords2D_(0),
refcount_vtexcoords3D_(0),
refcount_htexcoords1D_(0),
refcount_htexcoords2D_(0),
refcount_htexcoords3D_(0),
refcount_henormals_(0),
refcount_hecolors_(0),
refcount_ecolors_(0),
refcount_fnormals_(0),
refcount_fcolors_(0),
refcount_ftextureIndex_(0)
{
this->add_property( points_, "v:points" );
if (VAttribs & Attributes::Normal)
request_vertex_normals();
if (VAttribs & Attributes::Color)
request_vertex_colors();
if (VAttribs & Attributes::TexCoord1D)
request_vertex_texcoords1D();
if (VAttribs & Attributes::TexCoord2D)
request_vertex_texcoords2D();
if (VAttribs & Attributes::TexCoord3D)
request_vertex_texcoords3D();
if (HAttribs & Attributes::TexCoord1D)
request_halfedge_texcoords1D();
if (HAttribs & Attributes::TexCoord2D)
request_halfedge_texcoords2D();
if (HAttribs & Attributes::TexCoord3D)
request_halfedge_texcoords3D();
if (HAttribs & Attributes::Color)
request_halfedge_colors();
if (VAttribs & Attributes::Status)
Connectivity::request_vertex_status();
if (HAttribs & Attributes::Status)
Connectivity::request_halfedge_status();
if (HAttribs & Attributes::Normal)
request_halfedge_normals();
if (EAttribs & Attributes::Status)
Connectivity::request_edge_status();
if (EAttribs & Attributes::Color)
request_edge_colors();
if (FAttribs & Attributes::Normal)
request_face_normals();
if (FAttribs & Attributes::Color)
request_face_colors();
if (FAttribs & Attributes::Status)
Connectivity::request_face_status();
if (FAttribs & Attributes::TextureIndex)
request_face_texture_index();
//FIXME: data properties might actually cost storage even
//if there are no data traits??
this->add_property(data_vpph_);
this->add_property(data_fpph_);
this->add_property(data_hpph_);
this->add_property(data_epph_);
}
virtual ~AttribKernelT()
{
// should remove properties, but this will be done in
// BaseKernel's destructor anyway...
}
/** Assignment from another mesh of \em another type.
\note All that's copied is connectivity and vertex positions.
All other information (like e.g. attributes or additional
elements from traits classes) is not copied.
\note If you want to copy all information, including *custom* properties,
use PolyMeshT::operator=() instead.
*/
template <class _AttribKernel>
void assign(const _AttribKernel& _other, bool copyStandardProperties = false)
{
//copy standard properties if necessary
if(copyStandardProperties)
this->copy_all_kernel_properties(_other);
this->assign_connectivity(_other);
for (typename Connectivity::VertexIter v_it = Connectivity::vertices_begin();
v_it != Connectivity::vertices_end(); ++v_it)
{//assumes Point constructor supports cast from _AttribKernel::Point
set_point(*v_it, (Point)_other.point(*v_it));
}
//initialize standard properties if necessary
if(copyStandardProperties)
initializeStandardProperties();
}
//-------------------------------------------------------------------- points
const Point* points() const
{ return this->property(points_).data(); }
const Point& point(VertexHandle _vh) const
{ return this->property(points_, _vh); }
Point& point(VertexHandle _vh)
{ return this->property(points_, _vh); }
void set_point(VertexHandle _vh, const Point& _p)
{ this->property(points_, _vh) = _p; }
//------------------------------------------------------------ vertex normals
const Normal* vertex_normals() const
{ return this->property(vertex_normals_).data(); }
const Normal& normal(VertexHandle _vh) const
{ return this->property(vertex_normals_, _vh); }
void set_normal(VertexHandle _vh, const Normal& _n)
{ this->property(vertex_normals_, _vh) = _n; }
//------------------------------------------------------------- vertex colors
const Color* vertex_colors() const
{ return this->property(vertex_colors_).data(); }
const Color& color(VertexHandle _vh) const
{ return this->property(vertex_colors_, _vh); }
void set_color(VertexHandle _vh, const Color& _c)
{ this->property(vertex_colors_, _vh) = _c; }
//------------------------------------------------------- vertex 1D texcoords
const TexCoord1D* texcoords1D() const {
return this->property(vertex_texcoords1D_).data();
}
const TexCoord1D& texcoord1D(VertexHandle _vh) const {
return this->property(vertex_texcoords1D_, _vh);
}
void set_texcoord1D(VertexHandle _vh, const TexCoord1D& _t) {
this->property(vertex_texcoords1D_, _vh) = _t;
}
//------------------------------------------------------- vertex 2D texcoords
const TexCoord2D* texcoords2D() const {
return this->property(vertex_texcoords2D_).data();
}
const TexCoord2D& texcoord2D(VertexHandle _vh) const {
return this->property(vertex_texcoords2D_, _vh);
}
void set_texcoord2D(VertexHandle _vh, const TexCoord2D& _t) {
this->property(vertex_texcoords2D_, _vh) = _t;
}
//------------------------------------------------------- vertex 3D texcoords
const TexCoord3D* texcoords3D() const {
return this->property(vertex_texcoords3D_).data();
}
const TexCoord3D& texcoord3D(VertexHandle _vh) const {
return this->property(vertex_texcoords3D_, _vh);
}
void set_texcoord3D(VertexHandle _vh, const TexCoord3D& _t) {
this->property(vertex_texcoords3D_, _vh) = _t;
}
//.------------------------------------------------------ halfedge 1D texcoords
const TexCoord1D* htexcoords1D() const {
return this->property(halfedge_texcoords1D_).data();
}
const TexCoord1D& texcoord1D(HalfedgeHandle _heh) const {
return this->property(halfedge_texcoords1D_, _heh);
}
void set_texcoord1D(HalfedgeHandle _heh, const TexCoord1D& _t) {
this->property(halfedge_texcoords1D_, _heh) = _t;
}
//------------------------------------------------------- halfedge 2D texcoords
const TexCoord2D* htexcoords2D() const {
return this->property(halfedge_texcoords2D_).data();
}
const TexCoord2D& texcoord2D(HalfedgeHandle _heh) const {
return this->property(halfedge_texcoords2D_, _heh);
}
void set_texcoord2D(HalfedgeHandle _heh, const TexCoord2D& _t) {
this->property(halfedge_texcoords2D_, _heh) = _t;
}
//------------------------------------------------------- halfedge 3D texcoords
const TexCoord3D* htexcoords3D() const {
return this->property(halfedge_texcoords3D_).data();
}
const TexCoord3D& texcoord3D(HalfedgeHandle _heh) const {
return this->property(halfedge_texcoords3D_, _heh);
}
void set_texcoord3D(HalfedgeHandle _heh, const TexCoord3D& _t) {
this->property(halfedge_texcoords3D_, _heh) = _t;
}
//------------------------------------------------------------- edge colors
const Color* edge_colors() const
{ return this->property(edge_colors_).data(); }
const Color& color(EdgeHandle _eh) const
{ return this->property(edge_colors_, _eh); }
void set_color(EdgeHandle _eh, const Color& _c)
{ this->property(edge_colors_, _eh) = _c; }
//------------------------------------------------------------- halfedge normals
const Normal& normal(HalfedgeHandle _heh) const
{ return this->property(halfedge_normals_, _heh); }
void set_normal(HalfedgeHandle _heh, const Normal& _n)
{ this->property(halfedge_normals_, _heh) = _n; }
//------------------------------------------------------------- halfedge colors
const Color* halfedge_colors() const
{ return this->property(halfedge_colors_).data(); }
const Color& color(HalfedgeHandle _heh) const
{ return this->property(halfedge_colors_, _heh); }
void set_color(HalfedgeHandle _heh, const Color& _c)
{ this->property(halfedge_colors_, _heh) = _c; }
//-------------------------------------------------------------- face normals
const Normal& normal(FaceHandle _fh) const
{ return this->property(face_normals_, _fh); }
void set_normal(FaceHandle _fh, const Normal& _n)
{ this->property(face_normals_, _fh) = _n; }
//-------------------------------------------------------------- per Face Texture index
const TextureIndex& texture_index(FaceHandle _fh) const
{ return this->property(face_texture_index_, _fh); }
void set_texture_index(FaceHandle _fh, const TextureIndex& _t)
{ this->property(face_texture_index_, _fh) = _t; }
//--------------------------------------------------------------- face colors
const Color& color(FaceHandle _fh) const
{ return this->property(face_colors_, _fh); }
void set_color(FaceHandle _fh, const Color& _c)
{ this->property(face_colors_, _fh) = _c; }
//------------------------------------------------ request / alloc properties
void request_vertex_normals()
{
if (!refcount_vnormals_++)
this->add_property( vertex_normals_, "v:normals" );
}
void request_vertex_colors()
{
if (!refcount_vcolors_++)
this->add_property( vertex_colors_, "v:colors" );
}
void request_vertex_texcoords1D()
{
if (!refcount_vtexcoords1D_++)
this->add_property( vertex_texcoords1D_, "v:texcoords1D" );
}
void request_vertex_texcoords2D()
{
if (!refcount_vtexcoords2D_++)
this->add_property( vertex_texcoords2D_, "v:texcoords2D" );
}
void request_vertex_texcoords3D()
{
if (!refcount_vtexcoords3D_++)
this->add_property( vertex_texcoords3D_, "v:texcoords3D" );
}
void request_halfedge_texcoords1D()
{
if (!refcount_htexcoords1D_++)
this->add_property( halfedge_texcoords1D_, "h:texcoords1D" );
}
void request_halfedge_texcoords2D()
{
if (!refcount_htexcoords2D_++)
this->add_property( halfedge_texcoords2D_, "h:texcoords2D" );
}
void request_halfedge_texcoords3D()
{
if (!refcount_htexcoords3D_++)
this->add_property( halfedge_texcoords3D_, "h:texcoords3D" );
}
void request_edge_colors()
{
if (!refcount_ecolors_++)
this->add_property( edge_colors_, "e:colors" );
}
void request_halfedge_normals()
{
if (!refcount_henormals_++)
this->add_property( halfedge_normals_, "h:normals" );
}
void request_halfedge_colors()
{
if (!refcount_hecolors_++)
this->add_property( halfedge_colors_, "h:colors" );
}
void request_face_normals()
{
if (!refcount_fnormals_++)
this->add_property( face_normals_, "f:normals" );
}
void request_face_colors()
{
if (!refcount_fcolors_++)
this->add_property( face_colors_, "f:colors" );
}
void request_face_texture_index()
{
if (!refcount_ftextureIndex_++)
this->add_property( face_texture_index_, "f:textureindex" );
}
//------------------------------------------------- release / free properties
void release_vertex_normals()
{
if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_))
this->remove_property(vertex_normals_);
}
void release_vertex_colors()
{
if ((refcount_vcolors_ > 0) && (! --refcount_vcolors_))
this->remove_property(vertex_colors_);
}
void release_vertex_texcoords1D() {
if ((refcount_vtexcoords1D_ > 0) && (! --refcount_vtexcoords1D_))
this->remove_property(vertex_texcoords1D_);
}
void release_vertex_texcoords2D() {
if ((refcount_vtexcoords2D_ > 0) && (! --refcount_vtexcoords2D_))
this->remove_property(vertex_texcoords2D_);
}
void release_vertex_texcoords3D() {
if ((refcount_vtexcoords3D_ > 0) && (! --refcount_vtexcoords3D_))
this->remove_property(vertex_texcoords3D_);
}
void release_halfedge_texcoords1D() {
if ((refcount_htexcoords1D_ > 0) && (! --refcount_htexcoords1D_))
this->remove_property(halfedge_texcoords1D_);
}
void release_halfedge_texcoords2D() {
if ((refcount_htexcoords2D_ > 0) && (! --refcount_htexcoords2D_))
this->remove_property(halfedge_texcoords2D_);
}
void release_halfedge_texcoords3D() {
if ((refcount_htexcoords3D_ > 0) && (! --refcount_htexcoords3D_))
this->remove_property(halfedge_texcoords3D_);
}
void release_edge_colors()
{
if ((refcount_ecolors_ > 0) && (! --refcount_ecolors_))
this->remove_property(edge_colors_);
}
void release_halfedge_normals()
{
if ((refcount_henormals_ > 0) && (! --refcount_henormals_))
this->remove_property(halfedge_normals_);
}
void release_halfedge_colors()
{
if ((refcount_hecolors_ > 0) && (! --refcount_hecolors_))
this->remove_property(halfedge_colors_);
}
void release_face_normals()
{
if ((refcount_fnormals_ > 0) && (! --refcount_fnormals_))
this->remove_property(face_normals_);
}
void release_face_colors()
{
if ((refcount_fcolors_ > 0) && (! --refcount_fcolors_))
this->remove_property(face_colors_);
}
void release_face_texture_index()
{
if ((refcount_ftextureIndex_ > 0) && (! --refcount_ftextureIndex_))
this->remove_property(face_texture_index_);
}
//---------------------------------------------- dynamic check for properties
bool has_vertex_normals() const { return vertex_normals_.is_valid(); }
bool has_vertex_colors() const { return vertex_colors_.is_valid(); }
bool has_vertex_texcoords1D() const { return vertex_texcoords1D_.is_valid(); }
bool has_vertex_texcoords2D() const { return vertex_texcoords2D_.is_valid(); }
bool has_vertex_texcoords3D() const { return vertex_texcoords3D_.is_valid(); }
bool has_halfedge_texcoords1D() const { return halfedge_texcoords1D_.is_valid();}
bool has_halfedge_texcoords2D() const { return halfedge_texcoords2D_.is_valid();}
bool has_halfedge_texcoords3D() const { return halfedge_texcoords3D_.is_valid();}
bool has_edge_colors() const { return edge_colors_.is_valid(); }
bool has_halfedge_normals() const { return halfedge_normals_.is_valid(); }
bool has_halfedge_colors() const { return halfedge_colors_.is_valid(); }
bool has_face_normals() const { return face_normals_.is_valid(); }
bool has_face_colors() const { return face_colors_.is_valid(); }
bool has_face_texture_index() const { return face_texture_index_.is_valid(); }
public:
typedef VPropHandleT<Point> PointsPropertyHandle;
typedef VPropHandleT<Normal> VertexNormalsPropertyHandle;
typedef VPropHandleT<Color> VertexColorsPropertyHandle;
typedef VPropHandleT<TexCoord1D> VertexTexCoords1DPropertyHandle;
typedef VPropHandleT<TexCoord2D> VertexTexCoords2DPropertyHandle;
typedef VPropHandleT<TexCoord3D> VertexTexCoords3DPropertyHandle;
typedef HPropHandleT<TexCoord1D> HalfedgeTexCoords1DPropertyHandle;
typedef HPropHandleT<TexCoord2D> HalfedgeTexCoords2DPropertyHandle;
typedef HPropHandleT<TexCoord3D> HalfedgeTexCoords3DPropertyHandle;
typedef EPropHandleT<Color> EdgeColorsPropertyHandle;
typedef HPropHandleT<Normal> HalfedgeNormalsPropertyHandle;
typedef HPropHandleT<Color> HalfedgeColorsPropertyHandle;
typedef FPropHandleT<Normal> FaceNormalsPropertyHandle;
typedef FPropHandleT<Color> FaceColorsPropertyHandle;
typedef FPropHandleT<TextureIndex> FaceTextureIndexPropertyHandle;
public:
//standard vertex properties
PointsPropertyHandle points_pph() const
{ return points_; }
VertexNormalsPropertyHandle vertex_normals_pph() const
{ return vertex_normals_; }
VertexColorsPropertyHandle vertex_colors_pph() const
{ return vertex_colors_; }
VertexTexCoords1DPropertyHandle vertex_texcoords1D_pph() const
{ return vertex_texcoords1D_; }
VertexTexCoords2DPropertyHandle vertex_texcoords2D_pph() const
{ return vertex_texcoords2D_; }
VertexTexCoords3DPropertyHandle vertex_texcoords3D_pph() const
{ return vertex_texcoords3D_; }
//standard halfedge properties
HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_pph() const
{ return halfedge_texcoords1D_; }
HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_pph() const
{ return halfedge_texcoords2D_; }
HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_pph() const
{ return halfedge_texcoords3D_; }
// standard edge properties
HalfedgeNormalsPropertyHandle halfedge_normals_pph() const
{ return halfedge_normals_; }
// standard edge properties
HalfedgeColorsPropertyHandle halfedge_colors_pph() const
{ return halfedge_colors_; }
// standard edge properties
EdgeColorsPropertyHandle edge_colors_pph() const
{ return edge_colors_; }
//standard face properties
FaceNormalsPropertyHandle face_normals_pph() const
{ return face_normals_; }
FaceColorsPropertyHandle face_colors_pph() const
{ return face_colors_; }
FaceTextureIndexPropertyHandle face_texture_index_pph() const
{ return face_texture_index_; }
VertexData& data(VertexHandle _vh)
{ return this->property(data_vpph_, _vh); }
const VertexData& data(VertexHandle _vh) const
{ return this->property(data_vpph_, _vh); }
FaceData& data(FaceHandle _fh)
{ return this->property(data_fpph_, _fh); }
const FaceData& data(FaceHandle _fh) const
{ return this->property(data_fpph_, _fh); }
EdgeData& data(EdgeHandle _eh)
{ return this->property(data_epph_, _eh); }
const EdgeData& data(EdgeHandle _eh) const
{ return this->property(data_epph_, _eh); }
HalfedgeData& data(HalfedgeHandle _heh)
{ return this->property(data_hpph_, _heh); }
const HalfedgeData& data(HalfedgeHandle _heh) const
{ return this->property(data_hpph_, _heh); }
private:
//standard vertex properties
PointsPropertyHandle points_;
VertexNormalsPropertyHandle vertex_normals_;
VertexColorsPropertyHandle vertex_colors_;
VertexTexCoords1DPropertyHandle vertex_texcoords1D_;
VertexTexCoords2DPropertyHandle vertex_texcoords2D_;
VertexTexCoords3DPropertyHandle vertex_texcoords3D_;
//standard halfedge properties
HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_;
HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_;
HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_;
HalfedgeNormalsPropertyHandle halfedge_normals_;
HalfedgeColorsPropertyHandle halfedge_colors_;
// standard edge properties
EdgeColorsPropertyHandle edge_colors_;
//standard face properties
FaceNormalsPropertyHandle face_normals_;
FaceColorsPropertyHandle face_colors_;
FaceTextureIndexPropertyHandle face_texture_index_;
//data properties handles
DataVPropHandle data_vpph_;
DataHPropHandle data_hpph_;
DataEPropHandle data_epph_;
DataFPropHandle data_fpph_;
unsigned int refcount_vnormals_;
unsigned int refcount_vcolors_;
unsigned int refcount_vtexcoords1D_;
unsigned int refcount_vtexcoords2D_;
unsigned int refcount_vtexcoords3D_;
unsigned int refcount_htexcoords1D_;
unsigned int refcount_htexcoords2D_;
unsigned int refcount_htexcoords3D_;
unsigned int refcount_henormals_;
unsigned int refcount_hecolors_;
unsigned int refcount_ecolors_;
unsigned int refcount_fnormals_;
unsigned int refcount_fcolors_;
unsigned int refcount_ftextureIndex_;
/**
* @brief initializeStandardProperties Initializes the standard properties
* and sets refcount to 1 if found. (e.g. when the copy constructor was used)
*/
void initializeStandardProperties()
{
if(!this->get_property_handle(points_,
"v:points"))
{
//mesh has no points?
}
refcount_vnormals_ = this->get_property_handle(vertex_normals_,
"v:normals") ? 1 : 0 ;
refcount_vcolors_ = this->get_property_handle(vertex_colors_,
"v:colors") ? 1 : 0 ;
refcount_vtexcoords1D_ = this->get_property_handle(vertex_texcoords1D_,
"v:texcoords1D") ? 1 : 0 ;
refcount_vtexcoords2D_ = this->get_property_handle(vertex_texcoords2D_,
"v:texcoords2D") ? 1 : 0 ;
refcount_vtexcoords3D_ = this->get_property_handle(vertex_texcoords3D_,
"v:texcoords3D") ? 1 : 0 ;
refcount_htexcoords1D_ = this->get_property_handle(halfedge_texcoords1D_,
"h:texcoords1D") ? 1 : 0 ;
refcount_htexcoords2D_ = this->get_property_handle(halfedge_texcoords2D_,
"h:texcoords2D") ? 1 : 0 ;
refcount_htexcoords3D_ = this->get_property_handle(halfedge_texcoords3D_,
"h:texcoords3D") ? 1 : 0 ;
refcount_henormals_ = this->get_property_handle(halfedge_normals_,
"h:normals") ? 1 : 0 ;
refcount_hecolors_ = this->get_property_handle(halfedge_colors_,
"h:colors") ? 1 : 0 ;
refcount_ecolors_ = this->get_property_handle(edge_colors_,
"e:colors") ? 1 : 0 ;
refcount_fnormals_ = this->get_property_handle(face_normals_,
"f:normals") ? 1 : 0 ;
refcount_fcolors_ = this->get_property_handle(face_colors_,
"f:colors") ? 1 : 0 ;
refcount_ftextureIndex_ = this->get_property_handle(face_texture_index_,
"f:textureindex") ? 1 : 0 ;
}
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_ATTRIBKERNEL_HH defined
//=============================================================================

View File

@ -0,0 +1,103 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
/**
\file Attributes.hh
This file provides some macros containing attribute usage.
*/
#ifndef OPENMESH_ATTRIBUTES_HH
#define OPENMESH_ATTRIBUTES_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Mesh/Status.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace Attributes {
//== CLASS DEFINITION ========================================================
/** Attribute bits
*
* Use the bits to define a standard property at compile time using traits.
*
* \include traits5.cc
*
* \see \ref mesh_type
*/
enum AttributeBits
{
None = 0, ///< Clear all attribute bits
Normal = 1, ///< Add normals to mesh item (vertices/faces)
Color = 2, ///< Add colors to mesh item (vertices/faces/edges)
PrevHalfedge = 4, ///< Add storage for previous halfedge (halfedges). The bit is set by default in the DefaultTraits.
Status = 8, ///< Add status to mesh item (all items)
TexCoord1D = 16, ///< Add 1D texture coordinates (vertices, halfedges)
TexCoord2D = 32, ///< Add 2D texture coordinates (vertices, halfedges)
TexCoord3D = 64, ///< Add 3D texture coordinates (vertices, halfedges)
TextureIndex = 128 ///< Add texture index (faces)
};
//=============================================================================
} // namespace Attributes
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_ATTRIBUTES_HH defined
//=============================================================================

View File

@ -0,0 +1,826 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS BaseKernel
//
//=============================================================================
#ifndef OPENMESH_BASE_KERNEL_HH
#define OPENMESH_BASE_KERNEL_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
// --------------------
#include <vector>
#include <string>
#include <algorithm>
#include <iosfwd>
// --------------------
#include <OpenMesh/Core/Utils/PropertyContainer.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/// This class provides low-level property management like adding/removing
/// properties and access to properties. Under most circumstances, it is
/// advisable to use the high-level property management provided by
/// PropertyManager, instead.
///
/// All operations provided by %BaseKernel need at least a property handle
/// (VPropHandleT, EPropHandleT, HPropHandleT, FPropHandleT, MPropHandleT).
/// which keeps the data type of the property, too.
///
/// There are two types of properties:
/// -# Standard properties - mesh data (e.g. vertex normal or face color)
/// -# Custom properties - user defined data
///
/// The differentiation is only semantically, technically both are
/// equally handled. Therefore the methods provided by the %BaseKernel
/// are applicable to both property types.
///
/// \attention Since the class PolyMeshT derives from a kernel, hence all public
/// elements of %BaseKernel are usable.
class OPENMESHDLLEXPORT BaseKernel
{
public: //-------------------------------------------- constructor / destructor
BaseKernel() {}
virtual ~BaseKernel() {
vprops_.clear();
eprops_.clear();
hprops_.clear();
fprops_.clear();
}
public: //-------------------------------------------------- add new properties
/// \name Add a property to a mesh item
//@{
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper and/or one of its helper functions such as
* makePropertyManagerFromNew, makePropertyManagerFromExisting, or
* makePropertyManagerFromExistingOrNew.
*
* Adds a property
*
* Depending on the property handle type a vertex, (half-)edge, face or
* mesh property is added to the mesh. If the action fails the handle
* is invalid.
* On success the handle must be used to access the property data with
* property().
*
* \param _ph A property handle defining the data type to bind to mesh.
* On success the handle is valid else invalid.
* \param _name Optional name of property. Following restrictions apply
* to the name:
* -# Maximum length of name is 256 characters
* -# The prefixes matching "^[vhefm]:" are reserved for
* internal usage.
* -# The expression "^<.*>$" is reserved for internal usage.
*
*/
template <class T>
void add_property( VPropHandleT<T>& _ph, const std::string& _name="<vprop>")
{
_ph = VPropHandleT<T>( vprops_.add(T(), _name) );
vprops_.resize(n_vertices());
}
template <class T>
void add_property( HPropHandleT<T>& _ph, const std::string& _name="<hprop>")
{
_ph = HPropHandleT<T>( hprops_.add(T(), _name) );
hprops_.resize(n_halfedges());
}
template <class T>
void add_property( EPropHandleT<T>& _ph, const std::string& _name="<eprop>")
{
_ph = EPropHandleT<T>( eprops_.add(T(), _name) );
eprops_.resize(n_edges());
}
template <class T>
void add_property( FPropHandleT<T>& _ph, const std::string& _name="<fprop>")
{
_ph = FPropHandleT<T>( fprops_.add(T(), _name) );
fprops_.resize(n_faces());
}
template <class T>
void add_property( MPropHandleT<T>& _ph, const std::string& _name="<mprop>")
{
_ph = MPropHandleT<T>( mprops_.add(T(), _name) );
mprops_.resize(1);
}
//@}
public: //--------------------------------------------------- remove properties
/// \name Removing a property from a mesh tiem
//@{
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper to manage (and remove) properties.
*
* Remove a property.
*
* Removes the property represented by the handle from the apropriate
* mesh item.
* \param _ph Property to be removed. The handle is invalid afterwords.
*/
template <typename T>
void remove_property(VPropHandleT<T>& _ph)
{
if (_ph.is_valid())
vprops_.remove(_ph);
_ph.reset();
}
template <typename T>
void remove_property(HPropHandleT<T>& _ph)
{
if (_ph.is_valid())
hprops_.remove(_ph);
_ph.reset();
}
template <typename T>
void remove_property(EPropHandleT<T>& _ph)
{
if (_ph.is_valid())
eprops_.remove(_ph);
_ph.reset();
}
template <typename T>
void remove_property(FPropHandleT<T>& _ph)
{
if (_ph.is_valid())
fprops_.remove(_ph);
_ph.reset();
}
template <typename T>
void remove_property(MPropHandleT<T>& _ph)
{
if (_ph.is_valid())
mprops_.remove(_ph);
_ph.reset();
}
//@}
public: //------------------------------------------------ get handle from name
/// \name Get property handle by name
//@{
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper (e.g. PropertyManager::propertyExists) or one of
* its higher level helper functions such as
* makePropertyManagerFromExisting, or makePropertyManagerFromExistingOrNew.
*
* Retrieves the handle to a named property by it's name.
*
* \param _ph A property handle. On success the handle is valid else
* invalid.
* \param _name Name of wanted property.
* \return \c true if such a named property is available, else \c false.
*/
template <class T>
bool get_property_handle(VPropHandleT<T>& _ph,
const std::string& _name) const
{
return (_ph = VPropHandleT<T>(vprops_.handle(T(), _name))).is_valid();
}
template <class T>
bool get_property_handle(HPropHandleT<T>& _ph,
const std::string& _name) const
{
return (_ph = HPropHandleT<T>(hprops_.handle(T(), _name))).is_valid();
}
template <class T>
bool get_property_handle(EPropHandleT<T>& _ph,
const std::string& _name) const
{
return (_ph = EPropHandleT<T>(eprops_.handle(T(), _name))).is_valid();
}
template <class T>
bool get_property_handle(FPropHandleT<T>& _ph,
const std::string& _name) const
{
return (_ph = FPropHandleT<T>(fprops_.handle(T(), _name))).is_valid();
}
template <class T>
bool get_property_handle(MPropHandleT<T>& _ph,
const std::string& _name) const
{
return (_ph = MPropHandleT<T>(mprops_.handle(T(), _name))).is_valid();
}
//@}
public: //--------------------------------------------------- access properties
/// \name Access a property
//@{
/** In most cases you should use the convenient PropertyManager wrapper
* and use of this function should not be necessary. Under some
* circumstances, however (i.e. making a property persistent), it might be
* necessary to use this function.
*
* Access a property
*
* This method returns a reference to property. The property handle
* must be valid! The result is unpredictable if the handle is invalid!
*
* \param _ph A \em valid (!) property handle.
* \return The wanted property if the handle is valid.
*/
template <class T>
PropertyT<T>& property(VPropHandleT<T> _ph) {
return vprops_.property(_ph);
}
template <class T>
const PropertyT<T>& property(VPropHandleT<T> _ph) const {
return vprops_.property(_ph);
}
template <class T>
PropertyT<T>& property(HPropHandleT<T> _ph) {
return hprops_.property(_ph);
}
template <class T>
const PropertyT<T>& property(HPropHandleT<T> _ph) const {
return hprops_.property(_ph);
}
template <class T>
PropertyT<T>& property(EPropHandleT<T> _ph) {
return eprops_.property(_ph);
}
template <class T>
const PropertyT<T>& property(EPropHandleT<T> _ph) const {
return eprops_.property(_ph);
}
template <class T>
PropertyT<T>& property(FPropHandleT<T> _ph) {
return fprops_.property(_ph);
}
template <class T>
const PropertyT<T>& property(FPropHandleT<T> _ph) const {
return fprops_.property(_ph);
}
template <class T>
PropertyT<T>& mproperty(MPropHandleT<T> _ph) {
return mprops_.property(_ph);
}
template <class T>
const PropertyT<T>& mproperty(MPropHandleT<T> _ph) const {
return mprops_.property(_ph);
}
//@}
public: //-------------------------------------------- access property elements
/// \name Access a property element using a handle to a mesh item
//@{
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper.
*
* Return value of property for an item
*/
template <class T>
typename VPropHandleT<T>::reference
property(VPropHandleT<T> _ph, VertexHandle _vh) {
return vprops_.property(_ph)[_vh.idx()];
}
template <class T>
typename VPropHandleT<T>::const_reference
property(VPropHandleT<T> _ph, VertexHandle _vh) const {
return vprops_.property(_ph)[_vh.idx()];
}
template <class T>
typename HPropHandleT<T>::reference
property(HPropHandleT<T> _ph, HalfedgeHandle _hh) {
return hprops_.property(_ph)[_hh.idx()];
}
template <class T>
typename HPropHandleT<T>::const_reference
property(HPropHandleT<T> _ph, HalfedgeHandle _hh) const {
return hprops_.property(_ph)[_hh.idx()];
}
template <class T>
typename EPropHandleT<T>::reference
property(EPropHandleT<T> _ph, EdgeHandle _eh) {
return eprops_.property(_ph)[_eh.idx()];
}
template <class T>
typename EPropHandleT<T>::const_reference
property(EPropHandleT<T> _ph, EdgeHandle _eh) const {
return eprops_.property(_ph)[_eh.idx()];
}
template <class T>
typename FPropHandleT<T>::reference
property(FPropHandleT<T> _ph, FaceHandle _fh) {
return fprops_.property(_ph)[_fh.idx()];
}
template <class T>
typename FPropHandleT<T>::const_reference
property(FPropHandleT<T> _ph, FaceHandle _fh) const {
return fprops_.property(_ph)[_fh.idx()];
}
template <class T>
typename MPropHandleT<T>::reference
property(MPropHandleT<T> _ph) {
return mprops_.property(_ph)[0];
}
template <class T>
typename MPropHandleT<T>::const_reference
property(MPropHandleT<T> _ph) const {
return mprops_.property(_ph)[0];
}
//@}
public: //------------------------------------------------ copy property
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper (e.g. PropertyManager::copy_to or
* PropertyManager::copy).
*
* Copies a single property from one mesh element to another (of the same type)
*
* @param _ph A vertex property handle
* @param _vh_from From vertex handle
* @param _vh_to To vertex handle
*/
template <class T>
void copy_property(VPropHandleT<T>& _ph, VertexHandle _vh_from, VertexHandle _vh_to) {
if(_vh_from.is_valid() && _vh_to.is_valid())
vprops_.property(_ph)[_vh_to.idx()] = vprops_.property(_ph)[_vh_from.idx()];
}
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper (e.g. PropertyManager::copy_to or
* PropertyManager::copy).
*
* Copies a single property from one mesh element to another (of the same type)
*
* @param _ph A halfedge property handle
* @param _hh_from From halfedge handle
* @param _hh_to To halfedge handle
*/
template <class T>
void copy_property(HPropHandleT<T> _ph, HalfedgeHandle _hh_from, HalfedgeHandle _hh_to) {
if(_hh_from.is_valid() && _hh_to.is_valid())
hprops_.property(_ph)[_hh_to.idx()] = hprops_.property(_ph)[_hh_from.idx()];
}
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper (e.g. PropertyManager::copy_to or
* PropertyManager::copy).
*
* Copies a single property from one mesh element to another (of the same type)
*
* @param _ph An edge property handle
* @param _eh_from From edge handle
* @param _eh_to To edge handle
*/
template <class T>
void copy_property(EPropHandleT<T> _ph, EdgeHandle _eh_from, EdgeHandle _eh_to) {
if(_eh_from.is_valid() && _eh_to.is_valid())
eprops_.property(_ph)[_eh_to.idx()] = eprops_.property(_ph)[_eh_from.idx()];
}
/** You should not use this function directly. Instead, use the convenient
* PropertyManager wrapper (e.g. PropertyManager::copy_to or
* PropertyManager::copy).
*
* Copies a single property from one mesh element to another (of the same type)
*
* @param _ph A face property handle
* @param _fh_from From face handle
* @param _fh_to To face handle
*/
template <class T>
void copy_property(FPropHandleT<T> _ph, FaceHandle _fh_from, FaceHandle _fh_to) {
if(_fh_from.is_valid() && _fh_to.is_valid())
fprops_.property(_ph)[_fh_to.idx()] = fprops_.property(_ph)[_fh_from.idx()];
}
public:
//------------------------------------------------ copy all properties
/** Copies all properties from one mesh element to another (of the same type)
*
*
* @param _vh_from A vertex handle - source
* @param _vh_to A vertex handle - target
* @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied?
*/
void copy_all_properties(VertexHandle _vh_from, VertexHandle _vh_to, bool _copyBuildIn = false) {
for( PropertyContainer::iterator p_it = vprops_.begin();
p_it != vprops_.end(); ++p_it) {
// Copy all properties, if build in is true
// Otherwise, copy only properties without build in specifier
if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "v:" ) )
(*p_it)->copy(_vh_from.idx(), _vh_to.idx());
}
}
/** Copies all properties from one mesh element to another (of the same type)
*
* @param _hh_from A halfedge handle - source
* @param _hh_to A halfedge handle - target
* @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied?
*/
void copy_all_properties(HalfedgeHandle _hh_from, HalfedgeHandle _hh_to, bool _copyBuildIn = false) {
for( PropertyContainer::iterator p_it = hprops_.begin();
p_it != hprops_.end(); ++p_it) {
// Copy all properties, if build in is true
// Otherwise, copy only properties without build in specifier
if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "h:") )
(*p_it)->copy(_hh_from.idx(), _hh_to.idx());
}
}
/** Copies all properties from one mesh element to another (of the same type)
*
* @param _eh_from An edge handle - source
* @param _eh_to An edge handle - target
* @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied?
*/
void copy_all_properties(EdgeHandle _eh_from, EdgeHandle _eh_to, bool _copyBuildIn = false) {
for( PropertyContainer::iterator p_it = eprops_.begin();
p_it != eprops_.end(); ++p_it) {
// Copy all properties, if build in is true
// Otherwise, copy only properties without build in specifier
if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "e:") )
(*p_it)->copy(_eh_from.idx(), _eh_to.idx());
}
}
/** Copies all properties from one mesh element to another (of the same type)
*
* @param _fh_from A face handle - source
* @param _fh_to A face handle - target
* @param _copyBuildIn Should the internal properties (position, normal, texture coordinate,..) be copied?
*
*/
void copy_all_properties(FaceHandle _fh_from, FaceHandle _fh_to, bool _copyBuildIn = false) {
for( PropertyContainer::iterator p_it = fprops_.begin();
p_it != fprops_.end(); ++p_it) {
// Copy all properties, if build in is true
// Otherwise, copy only properties without build in specifier
if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "f:") )
(*p_it)->copy(_fh_from.idx(), _fh_to.idx());
}
}
/**
* @brief copy_all_kernel_properties uses the = operator to copy all properties from a given other BaseKernel.
* @param _other Another BaseKernel, to copy the properties from.
*/
void copy_all_kernel_properties(const BaseKernel & _other)
{
this->vprops_ = _other.vprops_;
this->eprops_ = _other.eprops_;
this->hprops_ = _other.hprops_;
this->fprops_ = _other.fprops_;
}
protected: //------------------------------------------------- low-level access
public: // used by non-native kernel and MeshIO, should be protected
size_t n_vprops(void) const { return vprops_.size(); }
size_t n_eprops(void) const { return eprops_.size(); }
size_t n_hprops(void) const { return hprops_.size(); }
size_t n_fprops(void) const { return fprops_.size(); }
size_t n_mprops(void) const { return mprops_.size(); }
BaseProperty* _get_vprop( const std::string& _name)
{ return vprops_.property(_name); }
BaseProperty* _get_eprop( const std::string& _name)
{ return eprops_.property(_name); }
BaseProperty* _get_hprop( const std::string& _name)
{ return hprops_.property(_name); }
BaseProperty* _get_fprop( const std::string& _name)
{ return fprops_.property(_name); }
BaseProperty* _get_mprop( const std::string& _name)
{ return mprops_.property(_name); }
const BaseProperty* _get_vprop( const std::string& _name) const
{ return vprops_.property(_name); }
const BaseProperty* _get_eprop( const std::string& _name) const
{ return eprops_.property(_name); }
const BaseProperty* _get_hprop( const std::string& _name) const
{ return hprops_.property(_name); }
const BaseProperty* _get_fprop( const std::string& _name) const
{ return fprops_.property(_name); }
const BaseProperty* _get_mprop( const std::string& _name) const
{ return mprops_.property(_name); }
BaseProperty& _vprop( size_t _idx ) { return vprops_._property( _idx ); }
BaseProperty& _eprop( size_t _idx ) { return eprops_._property( _idx ); }
BaseProperty& _hprop( size_t _idx ) { return hprops_._property( _idx ); }
BaseProperty& _fprop( size_t _idx ) { return fprops_._property( _idx ); }
BaseProperty& _mprop( size_t _idx ) { return mprops_._property( _idx ); }
const BaseProperty& _vprop( size_t _idx ) const
{ return vprops_._property( _idx ); }
const BaseProperty& _eprop( size_t _idx ) const
{ return eprops_._property( _idx ); }
const BaseProperty& _hprop( size_t _idx ) const
{ return hprops_._property( _idx ); }
const BaseProperty& _fprop( size_t _idx ) const
{ return fprops_._property( _idx ); }
const BaseProperty& _mprop( size_t _idx ) const
{ return mprops_._property( _idx ); }
size_t _add_vprop( BaseProperty* _bp ) { return vprops_._add( _bp ); }
size_t _add_eprop( BaseProperty* _bp ) { return eprops_._add( _bp ); }
size_t _add_hprop( BaseProperty* _bp ) { return hprops_._add( _bp ); }
size_t _add_fprop( BaseProperty* _bp ) { return fprops_._add( _bp ); }
size_t _add_mprop( BaseProperty* _bp ) { return mprops_._add( _bp ); }
protected: // low-level access non-public
BaseProperty& _vprop( BaseHandle _h )
{ return vprops_._property( _h.idx() ); }
BaseProperty& _eprop( BaseHandle _h )
{ return eprops_._property( _h.idx() ); }
BaseProperty& _hprop( BaseHandle _h )
{ return hprops_._property( _h.idx() ); }
BaseProperty& _fprop( BaseHandle _h )
{ return fprops_._property( _h.idx() ); }
BaseProperty& _mprop( BaseHandle _h )
{ return mprops_._property( _h.idx() ); }
const BaseProperty& _vprop( BaseHandle _h ) const
{ return vprops_._property( _h.idx() ); }
const BaseProperty& _eprop( BaseHandle _h ) const
{ return eprops_._property( _h.idx() ); }
const BaseProperty& _hprop( BaseHandle _h ) const
{ return hprops_._property( _h.idx() ); }
const BaseProperty& _fprop( BaseHandle _h ) const
{ return fprops_._property( _h.idx() ); }
const BaseProperty& _mprop( BaseHandle _h ) const
{ return mprops_._property( _h.idx() ); }
public: //----------------------------------------------------- element numbers
virtual size_t n_vertices() const { return 0; }
virtual size_t n_halfedges() const { return 0; }
virtual size_t n_edges() const { return 0; }
virtual size_t n_faces() const { return 0; }
protected: //------------------------------------------- synchronize properties
/// Reserves space for \p _n elements in all vertex property vectors.
void vprops_reserve(size_t _n) const { vprops_.reserve(_n); }
/// Resizes all vertex property vectors to the specified size.
void vprops_resize(size_t _n) const { vprops_.resize(_n); }
/**
* Same as vprops_resize() but ignores vertex property vectors that have
* a size larger than \p _n.
*
* Use this method instead of vprops_resize() if you plan to frequently reduce
* and enlarge the property container and you don't want to waste time
* reallocating the property vectors every time.
*/
void vprops_resize_if_smaller(size_t _n) const { vprops_.resize_if_smaller(_n); }
void vprops_clear() {
vprops_.clear();
}
void vprops_swap(unsigned int _i0, unsigned int _i1) const {
vprops_.swap(_i0, _i1);
}
void hprops_reserve(size_t _n) const { hprops_.reserve(_n); }
void hprops_resize(size_t _n) const { hprops_.resize(_n); }
void hprops_clear() {
hprops_.clear();
}
void hprops_swap(unsigned int _i0, unsigned int _i1) const {
hprops_.swap(_i0, _i1);
}
void eprops_reserve(size_t _n) const { eprops_.reserve(_n); }
void eprops_resize(size_t _n) const { eprops_.resize(_n); }
void eprops_clear() {
eprops_.clear();
}
void eprops_swap(unsigned int _i0, unsigned int _i1) const {
eprops_.swap(_i0, _i1);
}
void fprops_reserve(size_t _n) const { fprops_.reserve(_n); }
void fprops_resize(size_t _n) const { fprops_.resize(_n); }
void fprops_clear() {
fprops_.clear();
}
void fprops_swap(unsigned int _i0, unsigned int _i1) const {
fprops_.swap(_i0, _i1);
}
void mprops_resize(size_t _n) const { mprops_.resize(_n); }
void mprops_clear() {
mprops_.clear();
}
public:
// uses std::clog as output stream
void property_stats() const;
void property_stats(std::ostream& _ostr) const;
void vprop_stats( std::string& _string ) const;
void hprop_stats( std::string& _string ) const;
void eprop_stats( std::string& _string ) const;
void fprop_stats( std::string& _string ) const;
void mprop_stats( std::string& _string ) const;
// uses std::clog as output stream
void vprop_stats() const;
void hprop_stats() const;
void eprop_stats() const;
void fprop_stats() const;
void mprop_stats() const;
void vprop_stats(std::ostream& _ostr) const;
void hprop_stats(std::ostream& _ostr) const;
void eprop_stats(std::ostream& _ostr) const;
void fprop_stats(std::ostream& _ostr) const;
void mprop_stats(std::ostream& _ostr) const;
public:
typedef PropertyContainer::iterator prop_iterator;
typedef PropertyContainer::const_iterator const_prop_iterator;
prop_iterator vprops_begin() { return vprops_.begin(); }
prop_iterator vprops_end() { return vprops_.end(); }
const_prop_iterator vprops_begin() const { return vprops_.begin(); }
const_prop_iterator vprops_end() const { return vprops_.end(); }
prop_iterator eprops_begin() { return eprops_.begin(); }
prop_iterator eprops_end() { return eprops_.end(); }
const_prop_iterator eprops_begin() const { return eprops_.begin(); }
const_prop_iterator eprops_end() const { return eprops_.end(); }
prop_iterator hprops_begin() { return hprops_.begin(); }
prop_iterator hprops_end() { return hprops_.end(); }
const_prop_iterator hprops_begin() const { return hprops_.begin(); }
const_prop_iterator hprops_end() const { return hprops_.end(); }
prop_iterator fprops_begin() { return fprops_.begin(); }
prop_iterator fprops_end() { return fprops_.end(); }
const_prop_iterator fprops_begin() const { return fprops_.begin(); }
const_prop_iterator fprops_end() const { return fprops_.end(); }
prop_iterator mprops_begin() { return mprops_.begin(); }
prop_iterator mprops_end() { return mprops_.end(); }
const_prop_iterator mprops_begin() const { return mprops_.begin(); }
const_prop_iterator mprops_end() const { return mprops_.end(); }
private:
PropertyContainer vprops_;
PropertyContainer hprops_;
PropertyContainer eprops_;
PropertyContainer fprops_;
PropertyContainer mprops_;
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_BASE_KERNEL_HH defined
//=============================================================================

View File

@ -0,0 +1,97 @@
/* ========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-Aachen University *
* Department of Computer Graphics and Multimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* *
* 1. Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* 3. Neither the name of the copyright holder nor the names of its *
* contributors may be used to endorse or promote products derived from *
* this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS BaseMesh
//
//=============================================================================
#ifndef OPENMESH_BASEMESH_HH
#define OPENMESH_BASEMESH_HH
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Mesh/IteratorsT.hh>
#include <OpenMesh/Core/Mesh/CirculatorsT.hh>
#include <OpenMesh/Core/Mesh/Attributes.hh>
#include <vector>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/** \class BaseMesh BaseMesh.hh <OpenMesh/Mesh/BaseMesh.hh>
Base class for all meshes.
*/
class BaseMesh {
public:
virtual ~BaseMesh(void) {;}
};
//=============================================================================
} // namespace OpenMesh
//=============================================================================
//=============================================================================
#endif // OPENMESH_BASEMESH_HH defined
//=============================================================================

Some files were not shown because too many files have changed in this diff Show More