Initial commit
This commit is contained in:
commit
5d6a4935ec
1678 changed files with 351156 additions and 0 deletions
19
include/Camera.h
Normal file
19
include/Camera.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include "Object.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
struct Camera
|
||||
{
|
||||
// Origin or "eye"
|
||||
Eigen::Vector3d e;
|
||||
// orthonormal frame so that -w is the viewing direction.
|
||||
Eigen::Vector3d u,v,w;
|
||||
// image plane distance / focal length
|
||||
double d;
|
||||
// width and height of image plane
|
||||
double width, height;
|
||||
};
|
||||
|
||||
#endif
|
27
include/Object.h
Normal file
27
include/Object.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
||||
struct Ray;
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
// https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors
|
||||
virtual ~Object() {}
|
||||
// Intersect object with ray.
|
||||
//
|
||||
// Inputs:
|
||||
// Ray ray to intersect with
|
||||
// min_t minimum parametric distance to consider
|
||||
// Outputs:
|
||||
// t first intersection at ray.origin + t * ray.direction
|
||||
// n surface normal at point of intersection
|
||||
// Returns iff there a first intersection is found.
|
||||
//
|
||||
// The funny = 0 just ensures that this function is defined (as a no-op)
|
||||
virtual bool intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
27
include/Plane.h
Normal file
27
include/Plane.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef PLANE_H
|
||||
#define PLANE_H
|
||||
|
||||
#include "Object.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
class Plane : public Object
|
||||
{
|
||||
public:
|
||||
// Point on plane
|
||||
Eigen::Vector3d point;
|
||||
// Normal of plane
|
||||
Eigen::Vector3d normal;
|
||||
// Intersect plane with ray.
|
||||
//
|
||||
// Inputs:
|
||||
// Ray ray to intersect with
|
||||
// min_t minimum parametric distance to consider
|
||||
// Outputs:
|
||||
// t first intersection at ray.origin + t * ray.direction
|
||||
// n surface normal at point of intersection
|
||||
// Returns iff there a first intersection is found.
|
||||
bool intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const;
|
||||
};
|
||||
|
||||
#endif
|
15
include/Ray.h
Normal file
15
include/Ray.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef RAY_H
|
||||
#define RAY_H
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
||||
struct Ray
|
||||
{
|
||||
Eigen::Vector3d origin;
|
||||
// Not necessarily unit-length direction vector. (It is often useful to have
|
||||
// non-unit length so that origin+t*direction lands on a special point when
|
||||
// t=1.)
|
||||
Eigen::Vector3d direction;
|
||||
};
|
||||
|
||||
#endif
|
27
include/Sphere.h
Normal file
27
include/Sphere.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef SPHERE_H
|
||||
#define SPHERE_H
|
||||
|
||||
#include "Sphere.h"
|
||||
#include "Object.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
class Sphere : public Object
|
||||
{
|
||||
public:
|
||||
Eigen::Vector3d center;
|
||||
double radius;
|
||||
public:
|
||||
// Intersect sphere with ray.
|
||||
//
|
||||
// Inputs:
|
||||
// Ray ray to intersect with
|
||||
// min_t minimum parametric distance to consider
|
||||
// Outputs:
|
||||
// t first intersection at ray.origin + t * ray.direction
|
||||
// n surface normal at point of intersection
|
||||
// Returns iff there a first intersection is found.
|
||||
bool intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const;
|
||||
};
|
||||
|
||||
#endif
|
25
include/Triangle.h
Normal file
25
include/Triangle.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef TRIANGLE_H
|
||||
#define TRIANGLE_H
|
||||
|
||||
#include "Object.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
class Triangle : public Object
|
||||
{
|
||||
public:
|
||||
// A triangle has three corners
|
||||
std::tuple< Eigen::Vector3d, Eigen::Vector3d, Eigen::Vector3d> corners;
|
||||
// Intersect a triangle with ray.
|
||||
//
|
||||
// Inputs:
|
||||
// Ray ray to intersect with
|
||||
// min_t minimum parametric distance to consider
|
||||
// Outputs:
|
||||
// t first intersection at ray.origin + t * ray.direction
|
||||
// n surface normal at point of intersection
|
||||
// Returns iff there a first intersection is found.
|
||||
bool intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const;
|
||||
};
|
||||
|
||||
#endif
|
31
include/TriangleSoup.h
Normal file
31
include/TriangleSoup.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef TRIANGLE_SOUP_H
|
||||
#define TRIANGLE_SOUP_H
|
||||
|
||||
#include "Object.h"
|
||||
#include <Eigen/Core>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// Forward declaration
|
||||
class Triangle;
|
||||
class TriangleSoup : public Object
|
||||
{
|
||||
public:
|
||||
// A soup is just a set (list) of triangles
|
||||
std::vector<std::shared_ptr<Object> > triangles;
|
||||
|
||||
// Intersect a triangle soup with ray.
|
||||
//
|
||||
// Inputs:
|
||||
// Ray ray to intersect with
|
||||
// min_t minimum parametric distance to consider
|
||||
// Outputs:
|
||||
// t first intersection at ray.origin + t * ray.direction
|
||||
// n surface normal at point of intersection
|
||||
// Returns iff there a first intersection is found.
|
||||
bool intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
63
include/dirname.h
Normal file
63
include/dirname.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_DIRNAME_H
|
||||
#define IGL_DIRNAME_H
|
||||
#define IGL_INLINE inline
|
||||
#include <string>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
// Function like PHP's dirname: /etc/passwd --> /etc,
|
||||
// Input:
|
||||
// path string containing input path
|
||||
// Returns string containing dirname (see php's dirname)
|
||||
//
|
||||
// See also: basename, pathinfo
|
||||
IGL_INLINE std::string dirname(const std::string & path);
|
||||
}
|
||||
//
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
IGL_INLINE std::string igl::dirname(const std::string & path)
|
||||
{
|
||||
if(path == "")
|
||||
{
|
||||
return std::string("");
|
||||
}
|
||||
// https://stackoverflow.com/a/3071694/148668
|
||||
size_t found = path.find_last_of("/\\");
|
||||
if(found == std::string::npos)
|
||||
{
|
||||
// No slashes found
|
||||
return std::string(".");
|
||||
}else if(found == 0)
|
||||
{
|
||||
// Slash is first char
|
||||
return std::string(path.begin(),path.begin()+1);
|
||||
}else if(found == path.length()-1)
|
||||
{
|
||||
// Slash is last char
|
||||
std::string redo = std::string(path.begin(),path.end()-1);
|
||||
return igl::dirname(redo);
|
||||
}
|
||||
// Return everything up to but not including last slash
|
||||
return std::string(path.begin(),path.begin()+found);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
31
include/first_hit.h
Normal file
31
include/first_hit.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef FIRST_HIT_H
|
||||
#define FIRST_HIT_H
|
||||
|
||||
#include "Ray.h"
|
||||
#include "Object.h"
|
||||
#include <Eigen/Core>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
// Find the first (visible) hit given a ray and a collection of scene objects
|
||||
//
|
||||
// Inputs:
|
||||
// ray ray along which to search
|
||||
// min_t minimum t value to consider (for viewing rays, this is typically at
|
||||
// least the _parametric_ distance of the image plane to the camera)
|
||||
// objects list of objects (shapes) in the scene
|
||||
// Outputs:
|
||||
// hit_id index into objects of object with first hit
|
||||
// t _parametric_ distance along ray so that ray.origin+t*ray.direction is
|
||||
// the hit location
|
||||
// n surface normal at hit location
|
||||
// Returns true iff a hit was found
|
||||
bool first_hit(
|
||||
const Ray & ray,
|
||||
const double min_t,
|
||||
const std::vector< std::shared_ptr<Object> > & objects,
|
||||
int & hit_id,
|
||||
double & t,
|
||||
Eigen::Vector3d & n);
|
||||
|
||||
#endif
|
18590
include/json.hpp
Normal file
18590
include/json.hpp
Normal file
File diff suppressed because it is too large
Load diff
295
include/readSTL.h
Normal file
295
include/readSTL.h
Normal file
|
@ -0,0 +1,295 @@
|
|||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_READSTL_H
|
||||
#define IGL_READSTL_H
|
||||
# define IGL_INLINE inline
|
||||
|
||||
#ifndef IGL_NO_EIGEN
|
||||
# include <Eigen/Core>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
// Inputs:
|
||||
// stl_file pointer to already opened .stl file
|
||||
// Outputs:
|
||||
// stl_file closed file
|
||||
template <typename TypeV, typename TypeF, typename TypeN>
|
||||
IGL_INLINE bool readSTL(
|
||||
FILE * stl_file,
|
||||
std::vector<std::vector<TypeV> > & V,
|
||||
std::vector<std::vector<TypeF> > & F,
|
||||
std::vector<std::vector<TypeN> > & N);
|
||||
template <typename TypeV, typename TypeF, typename TypeN>
|
||||
IGL_INLINE bool readSTL(
|
||||
const std::string & filename,
|
||||
std::vector<std::vector<TypeV> > & V,
|
||||
std::vector<std::vector<TypeF> > & F,
|
||||
std::vector<std::vector<TypeN> > & N);
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <typename TypeV, typename TypeF, typename TypeN>
|
||||
IGL_INLINE bool igl::readSTL(
|
||||
const std::string & filename,
|
||||
std::vector<std::vector<TypeV> > & V,
|
||||
std::vector<std::vector<TypeF> > & F,
|
||||
std::vector<std::vector<TypeN> > & N)
|
||||
{
|
||||
using namespace std;
|
||||
// Should test for ascii
|
||||
|
||||
// Open file, and check for error
|
||||
FILE * stl_file = fopen(filename.c_str(),"rb");
|
||||
if(NULL==stl_file)
|
||||
{
|
||||
fprintf(stderr,"IOError: %s could not be opened...\n",
|
||||
filename.c_str());
|
||||
return false;
|
||||
}
|
||||
return readSTL(stl_file,V,F,N);
|
||||
}
|
||||
|
||||
template <typename TypeV, typename TypeF, typename TypeN>
|
||||
IGL_INLINE bool igl::readSTL(
|
||||
FILE * stl_file,
|
||||
std::vector<std::vector<TypeV> > & V,
|
||||
std::vector<std::vector<TypeF> > & F,
|
||||
std::vector<std::vector<TypeN> > & N)
|
||||
{
|
||||
using namespace std;
|
||||
//stl_file = freopen(NULL,"rb",stl_file);
|
||||
if(NULL==stl_file)
|
||||
{
|
||||
fprintf(stderr,"IOError: stl file could not be reopened as binary (1) ...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
V.clear();
|
||||
F.clear();
|
||||
N.clear();
|
||||
|
||||
|
||||
// Specifically 80 character header
|
||||
char header[80];
|
||||
char solid[80];
|
||||
bool is_ascii = true;
|
||||
if(fread(header,1,80,stl_file) != 80)
|
||||
{
|
||||
cerr<<"IOError: too short (1)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
sscanf(header,"%s",solid);
|
||||
if(string("solid") != solid)
|
||||
{
|
||||
// definitely **not** ascii
|
||||
is_ascii = false;
|
||||
}else
|
||||
{
|
||||
// might still be binary
|
||||
char buf[4];
|
||||
if(fread(buf,1,4,stl_file) != 4)
|
||||
{
|
||||
cerr<<"IOError: too short (3)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
size_t num_faces = *reinterpret_cast<unsigned int*>(buf);
|
||||
fseek(stl_file,0,SEEK_END);
|
||||
int file_size = ftell(stl_file);
|
||||
if(file_size == 80 + 4 + (4*12 + 2) * num_faces)
|
||||
{
|
||||
is_ascii = false;
|
||||
}else
|
||||
{
|
||||
is_ascii = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_ascii)
|
||||
{
|
||||
// Rewind to end of header
|
||||
//stl_file = fopen(filename.c_str(),"r");
|
||||
//stl_file = freopen(NULL,"r",stl_file);
|
||||
fseek(stl_file, 0, SEEK_SET);
|
||||
if(NULL==stl_file)
|
||||
{
|
||||
fprintf(stderr,"IOError: stl file could not be reopened as ascii ...\n");
|
||||
return false;
|
||||
}
|
||||
// Read 80 header
|
||||
// Eat file name
|
||||
#ifndef IGL_LINE_MAX
|
||||
# define IGL_LINE_MAX 2048
|
||||
#endif
|
||||
char name[IGL_LINE_MAX];
|
||||
if(NULL==fgets(name,IGL_LINE_MAX,stl_file))
|
||||
{
|
||||
cerr<<"IOError: ascii too short (2)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
// ascii
|
||||
while(true)
|
||||
{
|
||||
int ret;
|
||||
char facet[IGL_LINE_MAX],normal[IGL_LINE_MAX];
|
||||
vector<TypeN > n(3);
|
||||
double nd[3];
|
||||
ret = fscanf(stl_file,"%s %s %lg %lg %lg",facet,normal,nd,nd+1,nd+2);
|
||||
if(string("endsolid") == facet)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(ret != 5 ||
|
||||
!(string("facet") == facet ||
|
||||
string("faced") == facet) ||
|
||||
string("normal") != normal)
|
||||
{
|
||||
cout<<"facet: "<<facet<<endl;
|
||||
cout<<"normal: "<<normal<<endl;
|
||||
cerr<<"IOError: bad format (1)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
// copy casts to Type
|
||||
n[0] = (TypeN)nd[0];
|
||||
n[1] = (TypeN)nd[1];
|
||||
n[2] = (TypeN)nd[2];
|
||||
N.push_back(n);
|
||||
char outer[IGL_LINE_MAX], loop[IGL_LINE_MAX];
|
||||
ret = fscanf(stl_file,"%s %s",outer,loop);
|
||||
if(ret != 2 || string("outer") != outer || string("loop") != loop)
|
||||
{
|
||||
cerr<<"IOError: bad format (2)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
vector<TypeF> f;
|
||||
while(true)
|
||||
{
|
||||
char word[IGL_LINE_MAX];
|
||||
int ret = fscanf(stl_file,"%s",word);
|
||||
if(ret == 1 && string("endloop") == word)
|
||||
{
|
||||
break;
|
||||
}else if(ret == 1 && string("vertex") == word)
|
||||
{
|
||||
vector<TypeV> v(3);
|
||||
double vd[3];
|
||||
int ret = fscanf(stl_file,"%lg %lg %lg",vd,vd+1,vd+2);
|
||||
if(ret != 3)
|
||||
{
|
||||
cerr<<"IOError: bad format (3)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
f.push_back((TypeF)V.size());
|
||||
// copy casts to Type
|
||||
v[0] = vd[0];
|
||||
v[1] = vd[1];
|
||||
v[2] = vd[2];
|
||||
V.push_back(v);
|
||||
}else
|
||||
{
|
||||
cerr<<"IOError: bad format (4)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
}
|
||||
F.push_back(f);
|
||||
char endfacet[IGL_LINE_MAX];
|
||||
ret = fscanf(stl_file,"%s",endfacet);
|
||||
if(ret != 1 || string("endfacet") != endfacet)
|
||||
{
|
||||
cerr<<"IOError: bad format (5)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
}
|
||||
// read endfacet
|
||||
goto close_true;
|
||||
}else
|
||||
{
|
||||
// Binary
|
||||
//stl_file = freopen(NULL,"rb",stl_file);
|
||||
fseek(stl_file, 0, SEEK_SET);
|
||||
// Read 80 header
|
||||
char header[80];
|
||||
if(fread(header,sizeof(char),80,stl_file)!=80)
|
||||
{
|
||||
cerr<<"IOError: bad format (6)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
// Read number of triangles
|
||||
unsigned int num_tri;
|
||||
if(fread(&num_tri,sizeof(unsigned int),1,stl_file)!=1)
|
||||
{
|
||||
cerr<<"IOError: bad format (7)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
V.resize(num_tri*3,vector<TypeV >(3,0));
|
||||
N.resize(num_tri,vector<TypeN >(3,0));
|
||||
F.resize(num_tri,vector<TypeF >(3,0));
|
||||
for(int t = 0;t<(int)num_tri;t++)
|
||||
{
|
||||
// Read normal
|
||||
float n[3];
|
||||
if(fread(n,sizeof(float),3,stl_file)!=3)
|
||||
{
|
||||
cerr<<"IOError: bad format (8)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
// Read each vertex
|
||||
for(int c = 0;c<3;c++)
|
||||
{
|
||||
F[t][c] = 3*t+c;
|
||||
N[t][c] = (TypeN)n[c];
|
||||
float v[3];
|
||||
if(fread(v,sizeof(float),3,stl_file)!=3)
|
||||
{
|
||||
cerr<<"IOError: bad format (9)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
V[3*t+c][0] = v[0];
|
||||
V[3*t+c][1] = v[1];
|
||||
V[3*t+c][2] = v[2];
|
||||
}
|
||||
// Read attribute size
|
||||
unsigned short att_count;
|
||||
if(fread(&att_count,sizeof(unsigned short),1,stl_file)!=1)
|
||||
{
|
||||
cerr<<"IOError: bad format (10)."<<endl;
|
||||
goto close_false;
|
||||
}
|
||||
}
|
||||
goto close_true;
|
||||
}
|
||||
close_false:
|
||||
fclose(stl_file);
|
||||
return false;
|
||||
close_true:
|
||||
fclose(stl_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
// generated by autoexplicit.sh
|
||||
template bool igl::readSTL<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
// generated by autoexplicit.sh
|
||||
template bool igl::readSTL<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
// generated by autoexplicit.sh
|
||||
template bool igl::readSTL<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
// generated by autoexplicit.sh
|
||||
template bool igl::readSTL<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
template bool igl::readSTL<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
|
||||
template bool igl::readSTL<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
137
include/read_json.h
Normal file
137
include/read_json.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
#ifndef READ_JSON_H
|
||||
#define READ_JSON_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
// Forward declaration
|
||||
class Object;
|
||||
|
||||
// Read a scene description from a .json file
|
||||
//
|
||||
// Input:
|
||||
// filename path to .json file
|
||||
// Output:
|
||||
// camera camera looking at the scene
|
||||
// objects list of shared pointers to objects
|
||||
inline bool read_json(
|
||||
const std::string & filename,
|
||||
Camera & camera,
|
||||
std::vector<std::shared_ptr<Object> > & objects);
|
||||
|
||||
// Implementation
|
||||
|
||||
#include <json.hpp>
|
||||
#include "readSTL.h"
|
||||
#include "dirname.h"
|
||||
#include "Object.h"
|
||||
#include "Sphere.h"
|
||||
#include "Plane.h"
|
||||
#include "Triangle.h"
|
||||
#include "TriangleSoup.h"
|
||||
#include <Eigen/Geometry>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
inline bool read_json(
|
||||
const std::string & filename,
|
||||
Camera & camera,
|
||||
std::vector<std::shared_ptr<Object> > & objects)
|
||||
{
|
||||
// Heavily borrowing from
|
||||
// https://github.com/yig/graphics101-raycasting/blob/master/parser.cpp
|
||||
using json = nlohmann::json;
|
||||
|
||||
std::ifstream infile( filename );
|
||||
if( !infile ) return false;
|
||||
json j;
|
||||
infile >> j;
|
||||
|
||||
|
||||
// parse a vector
|
||||
auto parse_Vector3d = [](const json & j) -> Eigen::Vector3d
|
||||
{
|
||||
return Eigen::Vector3d(j[0],j[1],j[2]);
|
||||
};
|
||||
// parse camera
|
||||
auto parse_camera =
|
||||
[&parse_Vector3d](const json & j, Camera & camera)
|
||||
{
|
||||
assert(j["type"] == "perspective" && "Only handling perspective cameras");
|
||||
camera.d = j["focal_length"].get<double>();
|
||||
camera.e = parse_Vector3d(j["eye"]);
|
||||
camera.v = parse_Vector3d(j["up"]).normalized();
|
||||
camera.w = -parse_Vector3d(j["look"]).normalized();
|
||||
camera.u = camera.v.cross(camera.w);
|
||||
camera.height = j["height"].get<double>();
|
||||
camera.width = j["width"].get<double>();
|
||||
};
|
||||
parse_camera(j["camera"],camera);
|
||||
|
||||
auto parse_objects = [&parse_Vector3d,&filename](
|
||||
const json & j,
|
||||
std::vector<std::shared_ptr<Object> > & objects)
|
||||
{
|
||||
objects.clear();
|
||||
for(const json & jobj : j)
|
||||
{
|
||||
if(jobj["type"] == "sphere")
|
||||
{
|
||||
std::shared_ptr<Sphere> sphere(new Sphere());
|
||||
sphere->center = parse_Vector3d(jobj["center"]);
|
||||
sphere->radius = jobj["radius"].get<double>();
|
||||
objects.push_back(sphere);
|
||||
}else if(jobj["type"] == "plane")
|
||||
{
|
||||
std::shared_ptr<Plane> plane(new Plane());
|
||||
plane->point = parse_Vector3d(jobj["point"]);
|
||||
plane->normal = parse_Vector3d(jobj["normal"]).normalized();
|
||||
objects.push_back(plane);
|
||||
}else if(jobj["type"] == "triangle")
|
||||
{
|
||||
std::shared_ptr<Triangle> tri(new Triangle());
|
||||
tri->corners = std::make_tuple(
|
||||
parse_Vector3d(jobj["corners"][0]),
|
||||
parse_Vector3d(jobj["corners"][1]),
|
||||
parse_Vector3d(jobj["corners"][2]));
|
||||
objects.push_back(tri);
|
||||
}else if(jobj["type"] == "soup")
|
||||
{
|
||||
std::vector<std::vector<double> > V;
|
||||
std::vector<std::vector<double> > F;
|
||||
std::vector<std::vector<int> > N;
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#define PATH_SEPARATOR std::string("\\")
|
||||
#else
|
||||
#define PATH_SEPARATOR std::string("/")
|
||||
#endif
|
||||
const std::string stl_path = jobj["stl"];
|
||||
igl::readSTL(
|
||||
igl::dirname(filename)+
|
||||
PATH_SEPARATOR +
|
||||
stl_path,
|
||||
V,F,N);
|
||||
}
|
||||
std::shared_ptr<TriangleSoup> soup(new TriangleSoup());
|
||||
for(int f = 0;f<F.size();f++)
|
||||
{
|
||||
std::shared_ptr<Triangle> tri(new Triangle());
|
||||
tri->corners = std::make_tuple(
|
||||
Eigen::Vector3d( V[(long long)(F[f][0])][0], V[(long long)(F[f][0])][1], V[(long long)(F[f][0])][2]),
|
||||
Eigen::Vector3d( V[(long long)(F[f][1])][0], V[(long long)(F[f][1])][1], V[(long long)(F[f][1])][2]),
|
||||
Eigen::Vector3d( V[(long long)(F[f][2])][0], V[(long long)(F[f][2])][1], V[(long long)(F[f][2])][2])
|
||||
);
|
||||
soup->triangles.push_back(tri);
|
||||
}
|
||||
objects.push_back(soup);
|
||||
}
|
||||
}
|
||||
};
|
||||
parse_objects(j["objects"],objects);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
7890
include/stb_image.h
Normal file
7890
include/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
1724
include/stb_image_write.h
Normal file
1724
include/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load diff
26
include/viewing_ray.h
Normal file
26
include/viewing_ray.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef VIEWING_RAY_H
|
||||
#define VIEWING_RAY_H
|
||||
|
||||
#include "Ray.h"
|
||||
#include "Camera.h"
|
||||
|
||||
// Construct a viewing ray given a camera and subscripts to a pixel
|
||||
//
|
||||
// Inputs:
|
||||
// camera Perspective camera object
|
||||
// i pixel row index
|
||||
// j pixel column index
|
||||
// width number of pixels width of image
|
||||
// height number of pixels height of image
|
||||
// Outputs:
|
||||
// ray viewing ray starting at camera shooting through pixel. When t=1, then
|
||||
// ray.origin + t*ray.direction should land exactly on the center of the
|
||||
// pixel (i,j)
|
||||
void viewing_ray(
|
||||
const Camera & camera,
|
||||
const int i,
|
||||
const int j,
|
||||
const int width,
|
||||
const int height,
|
||||
Ray & ray);
|
||||
#endif
|
Reference in a new issue