123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // This file is part of libigl, a simple c++ geometry processing library.
- //
- // Copyright (C) 2014 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 "pseudonormal_test.h"
- #include "AABB.h"
- #include <cassert>
- IGL_INLINE void igl::pseudonormal_test(
- const Eigen::MatrixXd & V,
- const Eigen::MatrixXi & F,
- const Eigen::MatrixXd & FN,
- const Eigen::MatrixXd & VN,
- const Eigen::MatrixXd & EN,
- const Eigen::VectorXi & EMAP,
- const Eigen::RowVector3d & q,
- const int f,
- const Eigen::RowVector3d & c,
- double & s,
- Eigen::RowVector3d & n)
- {
- using namespace Eigen;
- const auto & qc = q-c;
- RowVector3d b;
- AABB<Eigen::MatrixXd,3>::barycentric_coordinates(
- c,V.row(F(f,0)),V.row(F(f,1)),V.row(F(f,2)),b);
- // Determine which normal to use
- const double epsilon = 1e-12;
- const int type = (b.array()<=epsilon).cast<int>().sum();
- switch(type)
- {
- case 2:
- // Find vertex
- for(int x = 0;x<3;x++)
- {
- if(b(x)>epsilon)
- {
- n = VN.row(F(f,x));
- break;
- }
- }
- break;
- case 1:
- // Find edge
- for(int x = 0;x<3;x++)
- {
- if(b(x)<=epsilon)
- {
- n = EN.row(EMAP(F.rows()*x+f));
- break;
- }
- }
- break;
- default:
- assert(false && "all barycentric coords zero.");
- case 0:
- n = FN.row(f);
- break;
- }
- s = (qc.dot(n) >= 0 ? 1. : -1.);
- }
- IGL_INLINE void igl::pseudonormal_test(
- const Eigen::MatrixXd & V,
- const Eigen::MatrixXi & E,
- const Eigen::MatrixXd & EN,
- const Eigen::MatrixXd & VN,
- const Eigen::RowVector2d & q,
- const int e,
- const Eigen::RowVector2d & c,
- double & s,
- Eigen::RowVector2d & n)
- {
- using namespace Eigen;
- const auto & qc = q-c;
- const double len = (V.row(E(e,1))-V.row(E(e,0))).norm();
- // barycentric coordinates
- RowVector2d b((c-V.row(E(e,1))).norm()/len,(c-V.row(E(e,0))).norm()/len);
- // Determine which normal to use
- const double epsilon = 1e-12;
- const int type = (b.array()<=epsilon).cast<int>().sum();
- switch(type)
- {
- case 1:
- // Find vertex
- for(int x = 0;x<2;x++)
- {
- if(b(x)>epsilon)
- {
- n = VN.row(E(e,x));
- break;
- }
- }
- break;
- default:
- assert(false && "all barycentric coords zero.");
- case 0:
- n = EN.row(e);
- break;
- }
- s = (qc.dot(n) >= 0 ? 1. : -1.);
- }
|