<commit_before>//#####################################################################
// Module fractal
//#####################################################################
#include <other/core/python/module.h>
#include <other/core/python/wrap.h>
#include <other/core/mesh/TriangleMesh.h>
#include <other/core/openmesh/TriMesh.h>
#include <other/core/python/stl.h>
#include <other/core/structure/Hashtable.h>
#include <other/core/structure/Tuple.h>
#include <other/core/structure/UnionFind.h>
#include <other/core/utility/curry.h>
#include <other/core/utility/Log.h>
#include <other/core/vector/Frame.h>
#include <other/core/vector/Matrix4x4.h>
#include <other/core/vector/normalize.h>
#include <other/core/solver/powell.h>
#include <tr1/unordered_map>
#include <vector>
using namespace other;

typedef real T;
typedef Vector<T,2> TV2;
typedef Vector<T,3> TV3;
using std::tr1::unordered_map;
using std::vector;
using Log::cout;
using std::endl;

static Array<int> boundary_edges_to_faces(const TriangleMesh& mesh, RawArray<const Vector<int,2>> edges) {
  Array<int> face(edges.size(),false);
  auto incident = mesh.incident_elements();
  for (int s=0;s<edges.size();s++) {
    OTHER_ASSERT(incident.valid(edges[s][0]));
    for (int t : incident[edges[s][0]])
      if (mesh.elements[t].contains(edges[s][1])) {
        face[s] = t;
        goto found;
      }
    OTHER_ASSERT(false);
    found:;
  }
  return face;
}

static vector<Array<Vector<T,2>>> iterate_L_system(real start_angle_per_level, real shrink_factor, const string& axiom, const unordered_map<char,string>& rules, const unordered_map<char,double>& turns, const int levels) {
  OTHER_ASSERT(levels>=0);
  vector<Array<TV2>> curves;
  string pattern = axiom;
  for (int level : range(levels+1)) {
    // Trace curve
    TV2 X;
    const double step = pow(shrink_factor,level);
    double angle = level*start_angle_per_level;
    Array<TV2> curve;
    curve.append(X);
    for (char c : pattern) {
      if (c=='f') {
        X += step*polar(angle);
        curve.append(X);
      } else {
        auto it = turns.find(c);
        if (it != turns.end())
          angle += it->second;
      }
    }
    if (pattern[pattern.size()-1]=='c') {
      OTHER_ASSERT(magnitude(curve[0]-curve.back())<.01*step);
      curve.pop();
    }
    curves.push_back(curve);
    if (level == levels)
      break;

    // Refine
    string fine;
    for (char c : pattern) {
      auto it = rules.find(c);
      if (it != rules.end())
        fine += it->second;
      else
        fine += c;
    }
    swap(pattern,fine);
  }
  return curves;
}

static Ref<TriangleMesh> branching_mesh(const int branching, const int levels, const int base, bool closed) {
  OTHER_ASSERT(branching>=2);
  OTHER_ASSERT(levels>=1);
  const int64_t count = (base-!closed)*(1+branching)*(1-(int64_t)pow((double)branching,levels))/(1-branching);
  OTHER_ASSERT(0<count && count<(1<<30));
  Array<Vector<int,3>> tris;
  tris.preallocate(count);
  int n = base-!closed;
  int lo = 0;
  for (int level=0;level<levels;level++) {
    const int hi = lo+n+1-closed,
              lom = n+1-closed,
              him = branching*n+1-closed;
    for (int i : range(n)) {
      const int a = lo+i,
                ap = lo+(i+1)%lom;
      const int b = hi+branching*i;
      const int mid = branching/2;
      tris.append_assuming_enough_space(vec(ap,a,b+mid));<commit_msg>Fix windows compile<commit_after>//#####################################################################
// Module fractal
//#####################################################################
#include <other/core/python/module.h>
#include <other/core/python/wrap.h>
#include <other/core/mesh/TriangleMesh.h>
#include <other/core/openmesh/TriMesh.h>
#include <other/core/python/stl.h>
#include <other/core/structure/Hashtable.h>
#include <other/core/structure/Tuple.h>
#include <other/core/structure/UnionFind.h>
#include <other/core/utility/curry.h>
#include <other/core/utility/Log.h>
#include <other/core/utility/tr1.h>
#include <other/core/vector/Frame.h>
#include <other/core/vector/Matrix4x4.h>
#include <other/core/vector/normalize.h>
#include <other/core/solver/powell.h>
#include <vector>
using namespace other;

typedef real T;
typedef Vector<T,2> TV2;
typedef Vector<T,3> TV3;
using std::vector;
using Log::cout;
using std::endl;

static Array<int> boundary_edges_to_faces(const TriangleMesh& mesh, RawArray<const Vector<int,2>> edges) {
  Array<int> face(edges.size(),false);
  auto incident = mesh.incident_elements();
  for (int s=0;s<edges.size();s++) {
    OTHER_ASSERT(incident.valid(edges[s][0]));
    for (int t : incident[edges[s][0]])
      if (mesh.elements[t].contains(edges[s][1])) {
        face[s] = t;
        goto found;
      }
    OTHER_ASSERT(false);
    found:;
  }
  return face;
}

static vector<Array<Vector<T,2>>> iterate_L_system(real start_angle_per_level, real shrink_factor, const string& axiom, const unordered_map<char,string>& rules, const unordered_map<char,double>& turns, const int levels) {
  OTHER_ASSERT(levels>=0);
  vector<Array<TV2>> curves;
  string pattern = axiom;
  for (int level : range(levels+1)) {
    // Trace curve
    TV2 X;
    const double step = pow(shrink_factor,level);
    double angle = level*start_angle_per_level;
    Array<TV2> curve;
    curve.append(X);
    for (char c : pattern) {
      if (c=='f') {
        X += step*polar(angle);
        curve.append(X);
      } else {
        auto it = turns.find(c);
        if (it != turns.end())
          angle += it->second;
      }
    }
    if (pattern[pattern.size()-1]=='c') {
      OTHER_ASSERT(magnitude(curve[0]-curve.back())<.01*step);
      curve.pop();
    }
    curves.push_back(curve);
    if (level == levels)
      break;

    // Refine
    string fine;
    for (char c : pattern) {
      auto it = rules.find(c);
      if (it != rules.end())
        fine += it->second;
      else
        fine += c;
    }
    swap(pattern,fine);
  }
  return curves;
}

static Ref<TriangleMesh> branching_mesh(const int branching, const int levels, const int base, bool closed) {
  OTHER_ASSERT(branching>=2);
  OTHER_ASSERT(levels>=1);
  const int64_t count = (base-!closed)*(1+branching)*(1-(int64_t)pow((double)branching,levels))/(1-branching);
  OTHER_ASSERT(0<count && count<(1<<30));
  Array<Vector<int,3>> tris;
  tris.preallocate(int(count));
  int n = base-!closed;
  int lo = 0;
  for (int level=0;level<levels;level++) {
    const int hi = lo+n+1-closed,
              lom = n+1-closed,
              him = branching*n+1-closed;
    for (int i : range(n)) {
      const int a = lo+i,
                ap = lo+(i+1)%lom;
      const int b = hi+branching*i;
      const int mid = branching/2;
      tris.append_assuming_enough_space(vec(ap,a,b+mid));
{'fraction_non_alphanumeric': 0.19613055678629449, 'fraction_numerical': 0.01284891448825875, 'mean_word_length': 3.5880758807588076, 'pattern_counts': {'":': 0, '<': 83, '<?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': '1393215', 'n_tokens_mistral': 2423, 'n_tokens_neox': 2330, 'n_words': 471}