<commit_before>// This file is part of libigl, a simple c++ geometry processing library.
// 
// Copyright (C) 2014 <NAME> <<EMAIL>>
// 
// 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_WINDINGNUMBERTREE_H
#define IGL_WINDINGNUMBERTREE_H
#include <list>
#include <map>
#include <Eigen/Dense>
#include "WindingNumberMethod.h"

static Eigen::MatrixXd dummyV;
namespace igl
{
  // Templates:
  //   Point  type for points in space, e.g. Eigen::Vector3d
  template <typename Point>
  class WindingNumberTree
  {
    public:
      // Method to use (see enum above)
      //static double min_max_w;
      static std::map< 
        std::pair<const WindingNumberTree*,const WindingNumberTree*>, double>
          cached;
    protected:
      WindingNumberMethod method;
      const WindingNumberTree * parent;
      std::list<WindingNumberTree * > children;
      //// List of boundary edges (recall edges are vertices in 2d)
      //const Eigen::MatrixXi boundary;
      // Base mesh vertices
      Eigen::MatrixXd & V;
      // Base mesh vertices with duplicates removed
      Eigen::MatrixXd SV;
      // Facets in this bounding volume
      Eigen::MatrixXi F;
      // Tesselated boundary curve
      Eigen::MatrixXi cap;
      // Upper Bound on radius of enclosing ball
      double radius;
      // (Approximate) center (of mass)
      Point center;
    public:
      inline WindingNumberTree():V(dummyV){}
      // For root
      inline WindingNumberTree(
        const Eigen::MatrixXd & V,
        const Eigen::MatrixXi & F);
      // For chilluns 
      inline WindingNumberTree(
        const WindingNumberTree<Point> & parent,
        const Eigen::MatrixXi & F);
      inline virtual ~WindingNumberTree();
      inline virtual void set_mesh(
        const Eigen::MatrixXd & V,
        const Eigen::MatrixXi & F);
      // Set method
      inline void set_method( const WindingNumberMethod & m);
    public:
      inline const Eigen::MatrixXd & getV() const;
      inline const Eigen::MatrixXi & getF() const;
      inline const Eigen::MatrixXi & getcap() const;
      // Grow the Tree recursively
      inline virtual void grow();
      // Determine whether a given point is inside the bounding 
      //
      // Inputs:
      //   p  query point 
      // Returns true if the point p is inside this bounding volume
      inline virtual bool inside(const Point & p) const;
      // Compute the (partial) winding number of a given point p
      // According to method
      //  
      // Inputs:
      //   p  query point 
      // Returns winding number 
      inline double winding_number(const Point & p) const;
      // Same as above, but always computes winding number using exact method
      // (sum over every facet)
      inline double winding_number_all(const Point & p) const;
      // Same as above, but always computes using sum over tesslated boundary
      inline double winding_number_boundary(const Point & p) const;
      //// Same as winding_number above, but if max_simple_abs_winding_number is
      //// less than some threshold min_max_w just return 0 (colloquially the "fast
      //// multipole method)
      ////
      ////
      //// Inputs:
      ////   p  query point 
      ////   min_max_w  minimum max simple w to be processed
      //// Returns approximate winding number
      //double winding_number_approx_simple(
      //  const Point & p, 
      //  const double min_max_w);
      // Print contents of Tree
      //
      // Optional input:
      //   tab  tab to show depth
      inline void print(const char * tab="");
      // Determine max absolute winding number
      //
      // Inputs:
      //   p  query point 
      // Returns max winding number of 
      inline virtual double max_abs_winding_number(const Point & p) const; 
      // Same as above, but stronger assumptions on (V,F). Assumes (V,F) is a
      // simple polyhedron
      inline virtual double max_simple_abs_winding_number(const Point & p) const;
      // Compute or read cached winding number for point p with respect to mesh
      // in bounding box, recursing according to approximation criteria
      //
      // Inputs:
      //   p  query point 
      //   that  WindingNumberTree containing mesh w.r.t. which we're computing w.n.
      // Returns cached winding number
      inline virtual double cached_winding_number(const WindingNumberTree & that, const Point & p) const;
  };
}

// Implementation

#include "WindingNumberTree.h"
#include "winding_number.h"
#include "triangle_fan.h"
#include "exterior_edges.h"

#include <igl/PI.h>
#include <igl/remove_duplicate_vertices.h>

#include <iostream>
#include <limits>

//template <typename Point>
//WindingNumberMethod WindingNumberTree<Point>::method = EXACT_WINDING_NUMBER_METHOD;
//template <typename Point>
//double WindingNumberTree<Point>::min_max_w = 0;
template <typename Point>
std::map< std::pair<const igl::WindingNumberTree<Point>*,const igl::WindingNumberTree<Point>*>, double>
  igl::WindingNumberTree<Point>::cached;

template <typename Point>
inline igl::WindingNumberTree<Point>::WindingNumberTree(
  const Eigen::MatrixXd & _V,
  const Eigen::MatrixXi & _F):
  method(EXACT_WINDING_NUMBER_METHOD),
  parent(NULL),
  V(dummyV),
  SV(),
  F(),
  //boundary(igl::boundary_facets<Eigen::MatrixXi,Eigen::MatrixXi>(F))
  cap(),
  radius(std::numeric_limits<double>::infinity()),
  center(0,0,0)
{
  set_mesh(V,F);
}

template <typename Point>
inline void igl::WindingNumberTree<Point>::set_mesh(
    const Eigen::MatrixXd & _V,
    const Eigen::MatrixXi & _F)
{
  // Remove any exactly duplicate vertices
  // Q: Can this ever increase the complexity of the boundary?
  // Q: Would we gain even more by remove almost exactly duplicate vertices?
  Eigen::MatrixXi SF,SVI,SVJ;
  igl::remove_duplicate_vertices(_V,_F,0.0,SV,SVI,SVJ,F);
  triangle_fan(exterior_edges(F),cap);
  V = SV;
}

template <typename Point>
inline igl::WindingNumberTree<Point>::WindingNumberTree(
  const igl::WindingNumberTree<Point> & parent,
  const Eigen::MatrixXi & _F):
  method(parent.method),
  parent(&parent),
  V(parent.V),
  SV(),
  F(_F),
  cap(triangle_fan(exterior_edges(_F)))
{
}

template <typename Point>
inline igl::WindingNumberTree<Point>::~WindingNumberTree()
{
  using namespace std;
  // Delete children
  typename list<WindingNumberTree<Point>* >::iterator cit = children.begin();
  while(cit != children.end())<commit_msg>bug in modified winding number<commit_after>// This file is part of libigl, a simple c++ geometry processing library.
// 
// Copyright (C) 2014 <NAME> <<EMAIL>>
// 
// 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_WINDINGNUMBERTREE_H
#define IGL_WINDINGNUMBERTREE_H
#include <list>
#include <map>
#include <Eigen/Dense>
#include "WindingNumberMethod.h"

static Eigen::MatrixXd dummyV;
namespace igl
{
  // Templates:
  //   Point  type for points in space, e.g. Eigen::Vector3d
  template <typename Point>
  class WindingNumberTree
  {
    public:
      // Method to use (see enum above)
      //static double min_max_w;
      static std::map< 
        std::pair<const WindingNumberTree*,const WindingNumberTree*>, double>
          cached;
    protected:
      WindingNumberMethod method;
      const WindingNumberTree * parent;
      std::list<WindingNumberTree * > children;
      //// List of boundary edges (recall edges are vertices in 2d)
      //const Eigen::MatrixXi boundary;
      // Base mesh vertices
      Eigen::MatrixXd & V;
      // Base mesh vertices with duplicates removed
      Eigen::MatrixXd SV;
      // Facets in this bounding volume
      Eigen::MatrixXi F;
      // Tesselated boundary curve
      Eigen::MatrixXi cap;
      // Upper Bound on radius of enclosing ball
      double radius;
      // (Approximate) center (of mass)
      Point center;
    public:
      inline WindingNumberTree():V(dummyV){}
      // For root
      inline WindingNumberTree(
        const Eigen::MatrixXd & V,
        const Eigen::MatrixXi & F);
      // For chilluns 
      inline WindingNumberTree(
        const WindingNumberTree<Point> & parent,
        const Eigen::MatrixXi & F);
      inline virtual ~WindingNumberTree();
      inline virtual void set_mesh(
        const Eigen::MatrixXd & V,
        const Eigen::MatrixXi & F);
      // Set method
      inline void set_method( const WindingNumberMethod & m);
    public:
      inline const Eigen::MatrixXd & getV() const;
      inline const Eigen::MatrixXi & getF() const;
      inline const Eigen::MatrixXi & getcap() const;
      // Grow the Tree recursively
      inline virtual void grow();
      // Determine whether a given point is inside the bounding 
      //
      // Inputs:
      //   p  query point 
      // Returns true if the point p is inside this bounding volume
      inline virtual bool inside(const Point & p) const;
      // Compute the (partial) winding number of a given point p
      // According to method
      //  
      // Inputs:
      //   p  query point 
      // Returns winding number 
      inline double winding_number(const Point & p) const;
      // Same as above, but always computes winding number using exact method
      // (sum over every facet)
      inline double winding_number_all(const Point & p) const;
      // Same as above, but always computes using sum over tesslated boundary
      inline double winding_number_boundary(const Point & p) const;
      //// Same as winding_number above, but if max_simple_abs_winding_number is
      //// less than some threshold min_max_w just return 0 (colloquially the "fast
      //// multipole method)
      ////
      ////
      //// Inputs:
      ////   p  query point 
      ////   min_max_w  minimum max simple w to be processed
      //// Returns approximate winding number
      //double winding_number_approx_simple(
      //  const Point & p, 
      //  const double min_max_w);
      // Print contents of Tree
      //
      // Optional input:
      //   tab  tab to show depth
      inline void print(const char * tab="");
      // Determine max absolute winding number
      //
      // Inputs:
      //   p  query point 
      // Returns max winding number of 
      inline virtual double max_abs_winding_number(const Point & p) const; 
      // Same as above, but stronger assumptions on (V,F). Assumes (V,F) is a
      // simple polyhedron
      inline virtual double max_simple_abs_winding_number(const Point & p) const;
      // Compute or read cached winding number for point p with respect to mesh
      // in bounding box, recursing according to approximation criteria
      //
      // Inputs:
      //   p  query point 
      //   that  WindingNumberTree containing mesh w.r.t. which we're computing w.n.
      // Returns cached winding number
      inline virtual double cached_winding_number(const WindingNumberTree & that, const Point & p) const;
  };
}

// Implementation

#include "WindingNumberTree.h"
#include "winding_number.h"
#include "triangle_fan.h"
#include "exterior_edges.h"

#include <igl/PI.h>
#include <igl/remove_duplicate_vertices.h>

#include <iostream>
#include <limits>

//template <typename Point>
//WindingNumberMethod WindingNumberTree<Point>::method = EXACT_WINDING_NUMBER_METHOD;
//template <typename Point>
//double WindingNumberTree<Point>::min_max_w = 0;
template <typename Point>
std::map< std::pair<const igl::WindingNumberTree<Point>*,const igl::WindingNumberTree<Point>*>, double>
  igl::WindingNumberTree<Point>::cached;

template <typename Point>
inline igl::WindingNumberTree<Point>::WindingNumberTree(
  const Eigen::MatrixXd & _V,
  const Eigen::MatrixXi & _F):
  method(EXACT_WINDING_NUMBER_METHOD),
  parent(NULL),
  V(dummyV),
  SV(),
  F(),
  //boundary(igl::boundary_facets<Eigen::MatrixXi,Eigen::MatrixXi>(F))
  cap(),
  radius(std::numeric_limits<double>::infinity()),
  center(0,0,0)
{
  set_mesh(_V,_F);
}

template <typename Point>
inline void igl::WindingNumberTree<Point>::set_mesh(
    const Eigen::MatrixXd & _V,
    const Eigen::MatrixXi & _F)
{
  using namespace std;
  // Remove any exactly duplicate vertices
  // Q: Can this ever increase the complexity of the boundary?
  // Q: Would we gain even more by remove almost exactly duplicate vertices?
  Eigen::MatrixXi SF,SVI,SVJ;
  igl::remove_duplicate_vertices(_V,_F,0.0,SV,SVI,SVJ,F);
  triangle_fan(exterior_edges(F),cap);
  V = SV;
}

template <typename Point>
inline igl::WindingNumberTree<Point>::WindingNumberTree(
  const igl::WindingNumberTree<Point> & parent,
  const Eigen::MatrixXi & _F):
  method(parent.method),
  parent(&parent),
  V(parent.V),
  SV(),
  F(_F),
  cap(triangle_fan(exterior_edges(_F)))
{
}

template <typename Point>
inline igl::WindingNumberTree<Point>::~WindingNumberTree()
{
  using namespace std;
  // Delete children
  typename list<WindingNumberTree<Point>* >::iterator cit = children.begin();
  while(cit != children.end())
{'fraction_non_alphanumeric': 0.1061134708737864, 'fraction_numerical': 0.0025788834951456312, 'mean_word_length': 2.92644431209053, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6177929', 'n_tokens_mistral': 4086, 'n_tokens_neox': 3854, 'n_words': 1232}