|
@@ -1,9 +1,9 @@
|
|
|
// 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
|
|
|
+//
|
|
|
+// 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 "reorient_facets_raycast.h"
|
|
|
#include "../per_face_normals.h"
|
|
@@ -17,8 +17,8 @@
|
|
|
#include <limits>
|
|
|
|
|
|
template <
|
|
|
- typename DerivedV,
|
|
|
- typename DerivedF,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedF,
|
|
|
typename DerivedI,
|
|
|
typename DerivedC>
|
|
|
IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
@@ -36,37 +36,37 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
using namespace std;
|
|
|
assert(F.cols() == 3);
|
|
|
assert(V.cols() == 3);
|
|
|
-
|
|
|
+
|
|
|
// number of faces
|
|
|
const int m = F.rows();
|
|
|
-
|
|
|
+
|
|
|
MatrixXi FF = F;
|
|
|
if (facet_wise) {
|
|
|
C.resize(m);
|
|
|
for (int i = 0; i < m; ++i) C(i) = i;
|
|
|
-
|
|
|
+
|
|
|
} else {
|
|
|
if (is_verbose) cout << "extracting patches... ";
|
|
|
bfs_orient(F,FF,C);
|
|
|
}
|
|
|
if (is_verbose) cout << (C.maxCoeff() + 1) << " components. ";
|
|
|
-
|
|
|
+
|
|
|
// number of patches
|
|
|
const int num_cc = C.maxCoeff()+1;
|
|
|
-
|
|
|
+
|
|
|
// Init Embree
|
|
|
EmbreeIntersector ei;
|
|
|
ei.init(V.template cast<float>(),FF);
|
|
|
-
|
|
|
+
|
|
|
// face normal
|
|
|
MatrixXd N;
|
|
|
per_face_normals(V,FF,N);
|
|
|
-
|
|
|
+
|
|
|
// face area
|
|
|
Matrix<typename DerivedV::Scalar,Dynamic,1> A;
|
|
|
doublearea(V,FF,A);
|
|
|
double area_total = A.sum();
|
|
|
-
|
|
|
+
|
|
|
// determine number of rays per component according to its area
|
|
|
VectorXd area_per_component;
|
|
|
area_per_component.setZero(num_cc);
|
|
@@ -80,7 +80,7 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
num_rays_per_component(c) = max<int>(static_cast<int>(rays_total * area_per_component(c) / area_total), rays_minimum);
|
|
|
}
|
|
|
rays_total = num_rays_per_component.sum();
|
|
|
-
|
|
|
+
|
|
|
// generate all the rays
|
|
|
if (is_verbose) cout << "generating rays... ";
|
|
|
uniform_real_distribution<float> rdist;
|
|
@@ -147,12 +147,12 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
}
|
|
|
}
|
|
|
if (is_verbose) cout << ray_face.size() << " rays. ";
|
|
|
-
|
|
|
+
|
|
|
// per component voting: first=front, second=back
|
|
|
vector<pair<float, float>> C_vote_distance(num_cc, make_pair(0, 0)); // sum of distance between ray origin and intersection
|
|
|
vector<pair<int , int >> C_vote_infinity(num_cc, make_pair(0, 0)); // number of rays reaching infinity
|
|
|
vector<pair<int , int >> C_vote_parity(num_cc, make_pair(0, 0)); // sum of parity count for each ray
|
|
|
-
|
|
|
+
|
|
|
if (is_verbose) cout << "shooting rays... ";
|
|
|
#pragma omp parallel for
|
|
|
for (int i = 0; i < (int)ray_face.size(); ++i)
|
|
@@ -161,7 +161,7 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
Vector3f o = ray_ori [i];
|
|
|
Vector3f d = ray_dir [i];
|
|
|
int c = C(f);
|
|
|
-
|
|
|
+
|
|
|
// shoot ray toward front & back
|
|
|
vector<Hit> hits_front;
|
|
|
vector<Hit> hits_back;
|
|
@@ -171,13 +171,13 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
ei.intersectRay(o, -d, hits_back , num_rays_back );
|
|
|
if (!hits_front.empty() && hits_front[0].id == f) hits_front.erase(hits_front.begin());
|
|
|
if (!hits_back .empty() && hits_back [0].id == f) hits_back .erase(hits_back .begin());
|
|
|
-
|
|
|
+
|
|
|
if (use_parity) {
|
|
|
#pragma omp atomic
|
|
|
C_vote_parity[c].first += hits_front.size() % 2;
|
|
|
#pragma omp atomic
|
|
|
C_vote_parity[c].second += hits_back .size() % 2;
|
|
|
-
|
|
|
+
|
|
|
} else {
|
|
|
if (hits_front.empty())
|
|
|
{
|
|
@@ -187,7 +187,7 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
#pragma omp atomic
|
|
|
C_vote_distance[c].first += hits_front[0].t;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (hits_back.empty())
|
|
|
{
|
|
|
#pragma omp atomic
|
|
@@ -198,14 +198,14 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
I.resize(m);
|
|
|
for(int f = 0; f < m; ++f)
|
|
|
{
|
|
|
int c = C(f);
|
|
|
if (use_parity) {
|
|
|
I(f) = C_vote_parity[c].first > C_vote_parity[c].second ? 1 : 0; // Ideally, parity for the front/back side should be 1/0 (i.e., parity sum for all rays should be smaller on the front side)
|
|
|
-
|
|
|
+
|
|
|
} else {
|
|
|
I(f) = (C_vote_infinity[c].first == C_vote_infinity[c].second && C_vote_distance[c].first < C_vote_distance[c].second) ||
|
|
|
C_vote_infinity[c].first < C_vote_infinity[c].second
|
|
@@ -219,8 +219,8 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
}
|
|
|
|
|
|
template <
|
|
|
- typename DerivedV,
|
|
|
- typename DerivedF,
|
|
|
+ typename DerivedV,
|
|
|
+ typename DerivedF,
|
|
|
typename DerivedFF,
|
|
|
typename DerivedI>
|
|
|
IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
@@ -255,4 +255,5 @@ IGL_INLINE void igl::embree::reorient_facets_raycast(
|
|
|
// Explicit template specialization
|
|
|
template void igl::embree::reorient_facets_raycast<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
|
template void igl::embree::reorient_facets_raycast<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<bool, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, bool, bool, bool, Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
|
+template void igl::embree::reorient_facets_raycast<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, int, bool, bool, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
|
#endif
|