123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // This file is part of libigl, a simple c++ geometry processing library.
- //
- // Copyright (C) 2016 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 "qslim_optimal_collapse_edge_callbacks.h"
- #include "quadric_binary_plus_operator.h"
- #include <Eigen/LU>
- IGL_INLINE void igl::qslim_optimal_collapse_edge_callbacks(
- Eigen::MatrixXi & E,
- std::vector<std::tuple<Eigen::MatrixXd,Eigen::RowVectorXd,double> > &
- quadrics,
- int & v1,
- int & v2,
- std::function<void(
- const int e,
- const Eigen::MatrixXd &,
- const Eigen::MatrixXi &,
- const Eigen::MatrixXi &,
- const Eigen::VectorXi &,
- const Eigen::MatrixXi &,
- const Eigen::MatrixXi &,
- double &,
- Eigen::RowVectorXd &)> & cost_and_placement,
- std::function<bool(
- const Eigen::MatrixXd & ,/*V*/
- const Eigen::MatrixXi & ,/*F*/
- const Eigen::MatrixXi & ,/*E*/
- const Eigen::VectorXi & ,/*EMAP*/
- const Eigen::MatrixXi & ,/*EF*/
- const Eigen::MatrixXi & ,/*EI*/
- const std::set<std::pair<double,int> > & ,/*Q*/
- const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
- const Eigen::MatrixXd & ,/*C*/
- const int /*e*/
- )> & pre_collapse,
- std::function<void(
- const Eigen::MatrixXd & , /*V*/
- const Eigen::MatrixXi & , /*F*/
- const Eigen::MatrixXi & , /*E*/
- const Eigen::VectorXi & ,/*EMAP*/
- const Eigen::MatrixXi & , /*EF*/
- const Eigen::MatrixXi & , /*EI*/
- const std::set<std::pair<double,int> > & , /*Q*/
- const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
- const Eigen::MatrixXd & , /*C*/
- const int , /*e*/
- const int , /*e1*/
- const int , /*e2*/
- const int , /*f1*/
- const int , /*f2*/
- const bool /*collapsed*/
- )> & post_collapse)
- {
- typedef std::tuple<Eigen::MatrixXd,Eigen::RowVectorXd,double> Quadric;
- cost_and_placement = [&quadrics,&v1,&v2](
- const int e,
- const Eigen::MatrixXd & V,
- const Eigen::MatrixXi & /*F*/,
- const Eigen::MatrixXi & E,
- const Eigen::VectorXi & /*EMAP*/,
- const Eigen::MatrixXi & /*EF*/,
- const Eigen::MatrixXi & /*EI*/,
- double & cost,
- Eigen::RowVectorXd & p)
- {
- // Combined quadric
- Quadric quadric_p;
- quadric_p = quadrics[E(e,0)] + quadrics[E(e,1)];
- // Quadric: p'Ap + 2b'p + c
- // optimal point: Ap = -b, or rather because we have row vectors: pA=-b
- const auto & A = std::get<0>(quadric_p);
- const auto & b = std::get<1>(quadric_p);
- const auto & c = std::get<2>(quadric_p);
- p = -b*A.inverse();
- cost = p.dot(p*A) + 2*p.dot(b) + c;
- // Force infs and nans to infinity
- if(std::isinf(cost) || cost!=cost)
- {
- cost = std::numeric_limits<double>::infinity();
- // Prevent NaNs. Actually NaNs might be useful for debugging.
- p.setConstant(0);
- }
- };
- // Remember endpoints
- pre_collapse = [&v1,&v2](
- const Eigen::MatrixXd & ,/*V*/
- const Eigen::MatrixXi & ,/*F*/
- const Eigen::MatrixXi & E,
- const Eigen::VectorXi & ,/*EMAP*/
- const Eigen::MatrixXi & ,/*EF*/
- const Eigen::MatrixXi & ,/*EI*/
- const std::set<std::pair<double,int> > & ,/*Q*/
- const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
- const Eigen::MatrixXd & ,/*C*/
- const int e)->bool
- {
- v1 = E(e,0);
- v2 = E(e,1);
- return true;
- };
- // update quadric
- post_collapse = [&v1,&v2,&quadrics](
- const Eigen::MatrixXd & , /*V*/
- const Eigen::MatrixXi & , /*F*/
- const Eigen::MatrixXi & , /*E*/
- const Eigen::VectorXi & ,/*EMAP*/
- const Eigen::MatrixXi & , /*EF*/
- const Eigen::MatrixXi & , /*EI*/
- const std::set<std::pair<double,int> > & , /*Q*/
- const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
- const Eigen::MatrixXd & , /*C*/
- const int , /*e*/
- const int , /*e1*/
- const int , /*e2*/
- const int , /*f1*/
- const int , /*f2*/
- const bool collapsed
- )->void
- {
- if(collapsed)
- {
- quadrics[v1<v2?v1:v2] = quadrics[v1] + quadrics[v2];
- }
- };
- }
|