Commit 7ab7a181 authored by Thomas's avatar Thomas

add export obj, function to slice a volume with a plane, extrusion of surfaces...

add export obj, function to slice a volume with a plane, extrusion of surfaces to volumes from lionel
parent f33a7c45
......@@ -37,24 +37,24 @@ SimpleGMap3::SimpleGMap3()
Algo::Modelisation::Primitive3D<PFP> primCat(myMap,position);
Dart d = primCat.hexaGrid_topo(3,1,1);
primCat.embedHexaGrid(2,1,1);
std::cout << "AAA"<< std::endl;
myMap.check();
std::cout << "AAA"<< std::endl;
DartMarker markOrient(myMap);
std::vector<Dart> orient;
FunctorStore fs(orient);
// DartMarker markOrient(myMap);
// std::vector<Dart> orient;
// FunctorStore fs(orient);
d = 49;
myMap.foreach_dart_of_oriented_volume(d, fs);
// d = 49;
// myMap.foreach_dart_of_oriented_volume(d, fs);
std::cout << "AAA"<< std::endl;
// for(std::vector<Dart>::iterator it = orient.begin() ; it != orient.end() ; ++it)
// markOrient.mark(*it);
for(std::vector<Dart>::iterator it = orient.begin() ; it != orient.end() ; ++it)
markOrient.mark(*it);
// SelectorMarked sm(markOrient);
// std::cout << "AAA"<< std::endl;
// Algo::Modelisation::catmullClarkVol<PFP,PFP::TVEC3,PFP::VEC3>(myMap, position, sm);
SelectorMarked sm(markOrient);
std::cout << "AAA"<< std::endl;
Algo::Modelisation::catmullClarkVol<PFP,PFP::TVEC3,PFP::VEC3>(myMap, position, sm);
// Geom::Plane3D<PFP::REAL> pl(VEC3(0.5,0.14,0.5),VEC3(1.5,0.45,0.5),VEC3(0.5,0.15,1.5));
Geom::Plane3D<PFP::REAL> pl(VEC3(-1,-0.5,-0.5),VEC3(-1,-0.5,0.5),VEC3(1,0.5,0.5));
Algo::Modelisation::sliceConvexVolume<PFP>(myMap, position, d, pl);
for(unsigned int i = position.begin() ; i != position.end() ; position.next(i))
position[i] += VEC3(2,0,0);
......@@ -114,6 +114,7 @@ void SimpleGMap3::cb_redraw()
glDisable(GL_LIGHTING);
glLineWidth(1.0f);
Algo::Render::GL1::renderTopoGMD3<PFP>(myMap, position, true, true, true, true, 0.9f, 0.9f, 0.9f, 0.9f);
// Algo::Render::GL1::renderTopoMD3<PFP>(myMap, position, true, true, true, 0.9f, 0.9f, 0.9f);
glDisable(GL_LIGHTING);
glColor3f(1.0f, 1.0f, 1.0f);
......
......@@ -28,6 +28,7 @@
#include "Topology/generic/parameters.h"
#include "Topology/gmap/embeddedGMap3.h"
//#include "Topology/map/embeddedMap3.h"
#include "Geometry/vector_gen.h"
......@@ -40,6 +41,7 @@ struct PFP: public PFP_STANDARD
{
// definition of the map
typedef EmbeddedGMap3 MAP ;
// typedef EmbeddedMap3 MAP ;
};
typedef PFP::MAP MAP ;
......
......@@ -54,6 +54,15 @@ bool exportPLY(typename PFP::MAP& map, const typename PFP::TVEC3& position, cons
template <typename PFP>
bool exportOFF(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good = allDarts) ;
/**
* export the map into a OBJ file
* @param the_map map to be exported
* @param filename filename of obj file
* @return true
*/
template <typename PFP>
bool exportOBJ(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good = allDarts) ;
/**
* export the map into a Trian file
* @param the_map map to be exported
......
......@@ -179,6 +179,72 @@ bool exportOFF(typename PFP::MAP& map, const typename PFP::TVEC3& position, cons
return true ;
}
template <typename PFP>
bool exportOBJ(typename PFP::MAP& map, const typename PFP::TVEC3& position, const char* filename, const FunctorSelect& good)
{
typedef typename PFP::MAP MAP;
typedef typename PFP::VEC3 VEC3;
std::ofstream out(filename, std::ios::out) ;
if (!out.good())
{
CGoGNerr << "Unable to open file " << CGoGNendl ;
return false ;
}
unsigned int nbDarts = map.getNbDarts() ;
std::vector<unsigned int> facesSize ;
std::vector<std::vector<unsigned int> > facesIdx ;
facesSize.reserve(nbDarts/3) ;
facesIdx.reserve(nbDarts/3) ;
std::map<unsigned int, unsigned int> vIndex ;
unsigned int vCpt = 0 ;
std::vector<unsigned int> vertices ;
vertices.reserve(nbDarts/6) ;
CellMarker markV(map, VERTEX) ;
TraversorF<MAP> t(map, good) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
std::vector<unsigned int> fidx ;
fidx.reserve(8) ;
Traversor2FV<typename PFP::MAP> tfv(map, d) ;
for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
{
unsigned int vNum = map.getEmbedding(VERTEX, it) ;
if(!markV.isMarked(it))
{
markV.mark(it) ;
vIndex[vNum] = vCpt++ ;
vertices.push_back(vNum) ;
}
fidx.push_back(vIndex[vNum]+1) ;
}
facesIdx.push_back(fidx) ;
}
out << "#OBJ - Export from CGoGN" << std::endl ;
for(unsigned int i = 0; i < vertices.size(); ++i)
{
const VEC3& v = position[vertices[i]] ;
out << "v " << v[0] << " " << v[1] << " " << v[2] << std::endl ;
}
out << std::endl;
for(unsigned int i = 0; i < facesIdx.size(); ++i)
{
out << "f ";
for(unsigned int j = 0; j < facesIdx[i].size(); ++j)
out << " " << facesIdx[i][j] ;
out << std::endl ;
}
out.close() ;
return true ;
}
template <typename PFP>
bool exportPlyPTMgeneric(typename PFP::MAP& map, const char* filename, const typename PFP::TVEC3& position, const FunctorSelect& good)
{
......
......@@ -129,7 +129,7 @@ typename PFP::VEC3 vertexBorderNormal(typename PFP::MAP& map, Dart d, const type
for(std::vector<Dart>::iterator it = faces.begin() ; it != faces.end() ; ++it)
{
if(!f.isMarked(*it) && map.phi3(*it)==*it)
if(!f.isMarked(*it) && map.isBoundaryFace(*it))
{
f.mark(*it);
VEC3 n = faceNormal<PFP>(map, *it, position);
......
......@@ -63,6 +63,20 @@ bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector
//bool importObjWithTex(typename PFP::MAP& map, const std::string& filename);
//
/**
* import a mesh and extrude all faces q
* @param map the map in which the function imports the mesh
* @param filename (*.{trian,trianbgz,off,obj,ply})
* @param positions table of vertices positions attribute
* @param m a marker that will be set by the function. If closeObject=false the phi2 that have fixed point are marked, else the created darts of the boundary are marked.
* @param kind what kind of mesh is the file (if none (-1) determined by filename extension) (cf enum in Mesh2Tables for other kind values)
* @param closeObject a boolean indicating if the imported mesh should be closed
* @return a boolean indicating if import was successfull
*/
template <typename PFP>
bool importMeshToExtrude(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind = ImportSurfacique::UNKNOWNSURFACE);
/*
* TODO a transformer en utilisant un MeshTableVolume.
......
......@@ -25,6 +25,7 @@
#include "Topology/generic/attributeHandler.h"
#include "Topology/generic/autoAttributeHandler.h"
#include "Container/fakeAttribute.h"
#include "Algo/Modelisation/polyhedron.h"
namespace CGoGN
{
......@@ -129,6 +130,114 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts)
return true ;
}
template <typename PFP>
bool importMeshSurfToVol(typename PFP::MAP& map, MeshTablesSurface<PFP>& mts, float dist)
{
AutoAttributeHandler< NoMathIONameAttribute< std::vector<Dart> > > vecDartsPerVertex(map, VERTEX, "incidents");
unsigned nbf = mts.getNbFaces();
int index = 0;
// buffer for tempo faces (used to remove degenerated edges)
std::vector<unsigned int> edgesBuffer;
edgesBuffer.reserve(16);
DartMarkerNoUnmark m(map) ;
AttributeHandler<typename PFP::VEC3> position = map.template getAttribute<typename PFP::VEC3>(VERTEX, "position");
std::vector<unsigned int > backEdgesBuffer(mts.getNbVertices(), EMBNULL);
// for each face of table -> create a prism
for(unsigned int i = 0; i < nbf; ++i)
{
// store face in buffer, removing degenerated edges
unsigned int nbe = mts.getNbEdgesFace(i);
edgesBuffer.clear();
unsigned int prec = EMBNULL;
for (unsigned int j = 0; j < nbe; ++j)
{
unsigned int em = mts.getEmbIdx(index++);
if (em != prec)
{
prec = em;
edgesBuffer.push_back(em);
}
}
// check first/last vertices
if (edgesBuffer.front() == edgesBuffer.back())
edgesBuffer.pop_back();
// create only non degenerated faces
nbe = edgesBuffer.size();
if (nbe > 2)
{
Dart d = Algo::Modelisation::createPrism<PFP>(map, nbe);
//Embed the base faces
for (unsigned int j = 0; j < nbe; ++j)
{
unsigned int em = edgesBuffer[j]; // get embedding
if(backEdgesBuffer[em] == EMBNULL)
{
unsigned int emn = map.newCell(VERTEX);
map.copyCell(VERTEX, emn, em);
backEdgesBuffer[em] = emn;
position[emn] += typename PFP::VEC3(0,0,dist);
}
FunctorSetEmb<typename PFP::MAP> fsetemb(map, VERTEX, em);
//foreach_dart_of_orbit_in_parent<typename PFP::MAP>(&map, VERTEX, d, fsetemb) ;
map.foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb);
//Embed the other base face
Dart d2 = map.phi1(map.phi1(map.phi2(d)));
unsigned int em2 = backEdgesBuffer[em];
FunctorSetEmb<typename PFP::MAP> fsetemb2(map, VERTEX, em2);
//foreach_dart_of_orbit_in_parent<typename PFP::MAP>(&map, VERTEX, d2, fsetemb2) ;
map.foreach_dart_of_orbit(PFP::MAP::ORBIT_IN_PARENT(VERTEX), d2, fsetemb2);
m.mark(d) ; // mark on the fly to unmark on second loop
vecDartsPerVertex[em].push_back(d); // store incident darts for fast adjacency reconstruction
d = map.phi_1(d);
}
}
}
// reconstruct neighbourhood
unsigned int nbBoundaryEdges = 0;
for (Dart d = map.begin(); d != map.end(); map.next(d))
{
if (m.isMarked(d))
{
// darts incident to end vertex of edge
std::vector<Dart>& vec = vecDartsPerVertex[map.phi1(d)];
unsigned int embd = map.getEmbedding(VERTEX, d);
Dart good_dart = NIL;
for (typename std::vector<Dart>::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it)
{
if (map.getEmbedding(VERTEX, map.phi1(*it)) == embd)
good_dart = *it;
}
if (good_dart != NIL)
{
map.sewVolumes(map.phi2(d), map.phi2(good_dart), false);
m.unmarkOrbit(EDGE, d);
}
else
{
m.unmark(d);
++nbBoundaryEdges;
}
}
}
map.closeMap();
return true ;
}
template <typename PFP>
bool importMesh(typename PFP::MAP& map, MeshTablesVolume<PFP>& mtv)
{
......@@ -442,6 +551,18 @@ bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector
return importMesh<PFP>(map, mts);
}
template <typename PFP>
bool importMeshToExtrude(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind)
{
float dist = 1.0f;
MeshTablesSurface<PFP> mts(map);
if(!mts.importMesh(filename, attrNames, kind))
return false;
return importMeshSurfToVol<PFP>(map, mts, dist);
}
/*
template <typename PFP>
bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, ImportVolumique::ImportType kind)
......
......@@ -111,8 +111,7 @@ bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector<
} while(ligne.size() == 0);
std::stringstream oss(ligne);
oss >> nbe; //number of vertices = 4
assert(nbe == 4);
oss >> nbe; //number of vertices = 4 or used for region mark
Dart d = Algo::Modelisation::Polyhedron<PFP>::createPolyhedron(map, 4);
......
......@@ -188,9 +188,9 @@ public:
static Dart createHexa(typename PFP::MAP& the_map);
/**
* create simple simple prism (not handled by Polyhedron object)
* create simple n-sided prism (not handled by Polyhedron object)
*/
static Dart createPrism(typename PFP::MAP& the_map);
static Dart createPrism(typename PFP::MAP& the_map, unsigned int nbSides);
/*
* get the reference dart
......
......@@ -237,30 +237,82 @@ Dart Polyhedron<PFP>::createHexa(typename PFP::MAP& the_map)
return base;
}
//template <typename PFP>
//Dart Polyhedron<PFP>::createPrism(typename PFP::MAP& the_map)
//{
// Dart base = the_map.newFace(3, false);
//
// Dart side1 = the_map.newFace(4, false);
// the_map.sewFaces(base, side1, false);
//
// Dart side2 = the_map.newFace(4, false);
// the_map.sewFaces(the_map.phi1(base), side2, false);
// the_map.sewFaces(the_map.phi_1(side1), the_map.phi1(side2), false);
//
// Dart side3 = the_map.newFace(4, false);
// the_map.sewFaces(the_map.phi1(the_map.phi1(base)), side3, false);
// the_map.sewFaces(the_map.phi_1(side2), the_map.phi1(side3), false);
//
// the_map.sewFaces(the_map.phi_1(side3), the_map.phi1(side1), false);
//
// Dart top = the_map.newFace(3, false);
// the_map.sewFaces(top, the_map.phi1(the_map.phi1(side1)), false);
// the_map.sewFaces(the_map.phi_1(top), the_map.phi1(the_map.phi1(side2)), false);
// the_map.sewFaces(the_map.phi1(top), the_map.phi1(the_map.phi1(side3)), false);
//
// return base;
//}
/**
* create a n-sided prism
*/
template <typename PFP>
Dart Polyhedron<PFP>::createPrism(typename PFP::MAP& the_map)
Dart createPrism(typename PFP::MAP& map, unsigned int n)
{
Dart base = the_map.newFace(3, false);
Dart side1 = the_map.newFace(4, false);
the_map.sewFaces(base, side1, false);
Dart side2 = the_map.newFace(4, false);
the_map.sewFaces(the_map.phi1(base), side2, false);
the_map.sewFaces(the_map.phi_1(side1), the_map.phi1(side2), false);
Dart dres = Dart::nil();
unsigned int nb = n*2;
std::vector<Dart> m_tableVertDarts;
m_tableVertDarts.reserve(nb);
Dart side3 = the_map.newFace(4, false);
the_map.sewFaces(the_map.phi1(the_map.phi1(base)), side3, false);
the_map.sewFaces(the_map.phi_1(side2), the_map.phi1(side3), false);
// creation of quads around circunference and storing vertices
for (unsigned int i = 0; i < n; ++i)
{
Dart d = map.newFace(4, false);
m_tableVertDarts.push_back(d);
}
the_map.sewFaces(the_map.phi_1(side3), the_map.phi1(side1), false);
// storing a dart from the vertex pointed by phi1(phi1(d))
for (unsigned int i = 0; i < n; ++i)
{
m_tableVertDarts.push_back(map.phi1(map.phi1(m_tableVertDarts[i])));
}
Dart top = the_map.newFace(3, false);
the_map.sewFaces(top, the_map.phi1(the_map.phi1(side1)), false);
the_map.sewFaces(the_map.phi_1(top), the_map.phi1(the_map.phi1(side2)), false);
the_map.sewFaces(the_map.phi1(top), the_map.phi1(the_map.phi1(side3)), false);
// sewing the quads
for (unsigned int i = 0; i < n-1; ++i)
{
Dart d = m_tableVertDarts[i];
d = map.phi_1(d);
Dart e = m_tableVertDarts[i+1];
e = map.phi1(e);
map.sewFaces(d, e, false);
}
//sewing the last with the first
map.sewFaces(map.phi1(m_tableVertDarts[0]), map.phi_1(m_tableVertDarts[n-1]), false);
//sewing the top & bottom faces
Dart d1 = map.newFace(n, false);
Dart d2 = map.newFace(n, false);
dres = d1;
for(unsigned int i = 0; i < n ; ++i)
{
map.sewFaces(m_tableVertDarts[i], d1, false);
map.sewFaces(m_tableVertDarts[n+i], d2, false);
d1 = map.phi1(d1);
d2 = map.phi_1(d2);
}
return base;
//return a dart from the base
return dres;
}
template <typename PFP>
......
......@@ -163,7 +163,7 @@ void quadranguleFaces(typename PFP::MAP& map, EMBV& attributs, const FunctorSele
do
{
mf.markOrbit(FACE, e);
e = map.phi2_1(e);
e = map.phi2(map.phi_1(e));
} while (e != cf);
}
}
......
......@@ -27,6 +27,7 @@
#include <math.h>
#include <vector>
#include "Geometry/plane_3d.h"
namespace CGoGN
{
......@@ -45,6 +46,13 @@ namespace Modelisation
template <typename PFP>
Dart cut3Ear(typename PFP::MAP& map, Dart d);
/**
* Cut a volume considering a plane
* @param d dart of the volume
* @return a dart from the face in the midle
*/
template <typename PFP>
Dart sliceConvexVolume(typename PFP::MAP& map, typename PFP::TVEC3& position, Dart d, Geom::Plane3D<typename PFP::REAL > pl);
/**
......
......@@ -25,6 +25,7 @@
#include "Algo/Geometry/centroid.h"
#include "Algo/Modelisation/subdivision.h"
#include "Algo/Modelisation/extrusion.h"
#include "Geometry/intersection.h"
namespace CGoGN
{
......@@ -82,6 +83,128 @@ Dart cut3Ear(typename PFP::MAP& map, Dart d)
return map.phi2(dRing);
}
template <typename PFP>
Dart sliceConvexVolume(typename PFP::MAP& map, typename PFP::TVEC3& position, Dart d, Geom::Plane3D<typename PFP::REAL > pl)
{
Dart dRes=NIL;
unsigned int nbInter = 0;
unsigned int nbVertices = 0;
CellMarkerStore vs(map, VERTEX); //marker for new vertices from edge cut
CellMarkerStore cf(map, FACE);
Dart dPath;
MarkerForTraversor<typename PFP::MAP::ParentMap > mte(map,EDGE);
MarkerForTraversor<typename PFP::MAP::ParentMap > mtf(map,FACE);
//search edges and vertices crossing the plane
Traversor3WE<typename PFP::MAP::ParentMap > te(map,d);
for(Dart dd = te.begin() ;dd != te.end() ; dd = te.next())
{
if(!mte.isMarked(dd))
{
if(fabs(pl.distance(position[dd]))<0.000001f)
{
nbVertices++;
vs.mark(dd); //mark vertex on slicing path
mte.mark(dd);
}
else
{
typename PFP::VEC3 interP;
typename PFP::VEC3 vec(Algo::Geometry::vectorOutOfDart<PFP>(map,dd,position));
Geom::Intersection inter = Geom::intersectionLinePlane<typename PFP::VEC3, typename Geom::Plane3D<typename PFP::REAL > >(position[dd],vec,pl,interP);
if(inter==Geom::FACE_INTERSECTION)
{
Dart dOp = map.phi1(dd);
typename PFP::VEC3 v2(interP-position[dd]);
typename PFP::VEC3 v3(interP-position[dOp]);
if(vec.norm2()>v2.norm2() && vec.norm2()>v3.norm2())
{
nbInter++;
cf.mark(dd); //mark face and opposite face to split
cf.mark(map.phi2(dd));
map.cutEdge(dd);
Dart dN = map.phi1(dd);
mte.mark(dN);
vs.mark(dN); //mark vertex for split
position[dN] = interP; //place
}
}
}
}
}
// std::cout << "edges cut: " << nbInter << std::endl;
unsigned int nbSplit=0;
//slice when at least two edges are concerned
if(nbInter>1)
{
Traversor3WF<typename PFP::MAP::ParentMap > tf(map,d);
for(Dart dd = tf.begin() ; dd != tf.end() ; dd = tf.next())
{
//for faces with a new vertex
if(cf.isMarked(dd))
{
cf.unmark(dd);
Dart dS = dd;
bool split=false;
do {
//find the new vertex
if(vs.isMarked(dS))
{
Dart dSS = map.phi1(dS);
//search an other new vertex (or an existing vertex intersected with the plane) in order to split the face
do {
if(vs.isMarked(dSS))
{
nbSplit++;
map.splitFace(dS,dSS);
dPath=map.phi_1(dS);
split=true;
}
dSS = map.phi1(dSS);
} while(!split && dSS!=dS);
}
dS = map.phi1(dS);
} while(!split && dS!=dd);
}
}
// std::cout << "face split " << nbSplit << std::endl;
//define the path to split
std::vector<Dart> vPath;
vPath.reserve((nbSplit+nbVertices)+1);
vPath.push_back(dPath);
for(std::vector<Dart>::iterator it = vPath.begin() ;it != vPath.end() ; ++it)
{
Dart dd = map.phi1(*it);
Dart ddd = map.phi1(map.phi2(dd));
while(!vs.isMarked(map.phi1(ddd)) && ddd!=dd)
ddd = map.phi1(map.phi2(ddd));
if(vs.isMarked(map.phi1(ddd)) && !map.sameVertex(ddd,*vPath.begin()))
vPath.push_back(ddd);
}
assert(vPath.size()>2);
map.splitVolume(vPath);
dRes = map.phi2(*vPath.begin());
}
return dRes;
}
template <typename PFP, typename EMBV, typename EMB>
void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected)
{
......
......@@ -56,7 +56,18 @@ template <typename VEC3>
Intersection intersectionLinePlane(const VEC3& P, const VEC3& Dir, const VEC3& PlaneP, const VEC3& NormP, VEC3& Inter) ;
/**
* test the intersection between a ray and a triangle (optimized version with triple product
* test the intersection between a line and a triangle
* @param P a point on the line
* @param Dir line direction
* @param Plane plane
* @param Inter store the intersection point
* @return the intersection ( FACE_INTERSECTION = OK, EDGE_INTERSECTION = line inside of plane)
*/
template <typename VEC3, typename PLANE>
Intersection intersectionLinePlane(const VEC3& P, const VEC3& Dir, const PLANE& Plane, VEC3& Inter) ;
/**
* test the intersection between a ray and a triangle (optimized version with triple product)
* @param P a point on the line
* @param Dir line direction
* @param Ta triangle point 1
......@@ -69,7 +80,7 @@ template <typename VEC3>
Intersection intersectionRayTriangle(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter) ;
/**
* test the intersection between a ray and a triangle (optimized version with triple product
* test the intersection between a ray and a triangle (optimized version with triple product)
* @param P a point on the line
* @param Dir line direction
* @param Ta triangle point 1
......@@ -82,7 +93,7 @@ template <typename VEC3>
Intersection intersectionRayTriangleOpt(const VEC3& P, const VEC3& Dir, const VEC3& Ta, const VEC3& Tb, const VEC3& Tc, VEC3& Inter);
/**
* test the intersection between a ray and a triangle (optimized version with triple product
* test the intersection between a ray and a triangle (optimized version with triple product)
* @param P a point on the line
* @param Dir line direction
* @param Ta triangle point 1
......
......@@ -33,21 +33,29 @@ Intersection intersectionLinePlane(const VEC3& P, const VEC3& Dir, const VEC3& P
{
float b = NormP * Dir ;
#define PRECISION 1e-20
#define PRECISION 1e-6
if (fabs(b) < PRECISION) //ray parallel to triangle
{
VEC3 v = PlaneP - P ;
float c = NormP * v ;
VEC3 v = PlaneP - P;
float c = NormP * v;
if (fabs(c) < PRECISION )
return EDGE_INTERSECTION ;
return NO_INTERSECTION ;
return EDGE_INTERSECTION;
return NO_INTERSECTION;
}
#undef PRECISION
float a = NormP * (PlaneP - P) ;
float a = NormP * (PlaneP - P);
Inter = P + (a / b) * Dir;
Inter = P + (a / b) * Dir ;
return FACE_INTERSECTION ;
return FACE_INTERSECTION;
}