<commit_before>#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

#include "geometry/extrusion.h"
#include "geometry/vtk_utils.h"
#include "geometry/vtk_debug.h"
#include "process_planning/surface_planning.h"
#include "system/parse_stl.h"

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QHBoxLayout>

using namespace gca;

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
{

  current_mode = SLICE_MODE;

  vtk_window = new QVTKWidget(this, Qt::Widget);

  QHBoxLayout *layout = new QHBoxLayout;

  QPushButton* button2 = new QPushButton("Load STL");
  accept_button = new QPushButton("Accept slice", this);
  reject_button = new QPushButton("Reject slice", this);
  set_done_button = new QPushButton("Done with part", this);

  QVBoxLayout* update_buttons = new QVBoxLayout();
  update_buttons->addWidget(button2);
  update_buttons->addWidget(accept_button);
  update_buttons->addWidget(reject_button);
  update_buttons->addWidget(set_done_button);

  in_progress_heading = new QLabel();
  in_progress_heading->setText("In Progress");

  QVBoxLayout* in_progress = new QVBoxLayout();
  in_progress->addWidget(in_progress_heading);

  QLabel* completed_heading = new QLabel();
  completed_heading->setText("Completed");

  QVBoxLayout* completed = new QVBoxLayout();
  completed->addWidget(completed_heading);

  layout->addLayout(update_buttons);
  layout->addWidget(vtk_window);
  layout->addLayout(in_progress);
  layout->addLayout(completed);

  setCentralWidget(new QWidget);
  centralWidget()->setLayout(layout);

  connect(accept_button, SIGNAL (released()), this, SLOT (handle_accept()));
  connect(reject_button, SIGNAL (released()), this, SLOT (handle_reject()));
  connect(set_done_button, SIGNAL (released()), this, SLOT (handle_set_done()));

  // active_mesh =
  //   parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/artusitestp1 - Part 1.stl", 0.0001);
  
  active_mesh =
    parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/caliperbedlevelingi3v2_fixed - Part 1.stl", 0.0001);

  //parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/SmallReverseCameraMount - Part 1.stl", 0.0001);

  slice_planes = possible_slice_planes(active_mesh);

  DBG_ASSERT(slice_planes.size() > 0);

  active_plane = slice_planes.back();
  slice_planes.pop_back();

  active_plane_actor = plane_actor(vtk_plane(active_plane));

  active_mesh_polydata = polydata_for_trimesh(active_mesh);
  color_polydata(active_mesh_polydata, 0, 255, 0);

  vtkSmartPointer<vtkPolyDataMapper> mapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(active_mesh_polydata);

  active_mesh_actor = 
    vtkSmartPointer<vtkActor>::New();
  active_mesh_actor->SetMapper(mapper);

  renderer = vtkSmartPointer<vtkRenderer>::New();

  renderer->SetBackground(1, 1, 1);
  renderer->AddActor(active_mesh_actor);
  renderer->AddActor(active_plane_actor);

  vtk_window->GetRenderWindow()->AddRenderer(renderer);

  vtk_window->show();

}

polygon_3 build_2D_circle(const double radius) {
  // typedef boost::geometry::model::d2::point_xy<double> point;
  // typedef boost::geometry::model::polygon<point> polygon;

  // Declare the point_circle strategy
  boost::geometry::strategy::buffer::point_circle point_strategy(360);

  // Declare other strategies
  boost::geometry::strategy::buffer::distance_symmetric<double> distance_strategy(radius);
  boost::geometry::strategy::buffer::join_round join_strategy;
  boost::geometry::strategy::buffer::end_round end_strategy;
  boost::geometry::strategy::buffer::side_straight side_strategy;

  // Declare/fill of a multi point
  boost::geometry::model::multi_point<boost_point_2> mp;
  boost::geometry::read_wkt("MULTIPOINT((0 0))", mp); //,(3 4),(4 4),(7 3))", mp);

  // Create the buffer of a multi point
  boost_multipoly_2 result;
  boost::geometry::buffer(mp, result,
			  distance_strategy, side_strategy,
			  join_strategy, end_strategy, point_strategy);

  DBG_ASSERT(result.size() == 1);

  boost_poly_2 front = result.front();

  return to_polygon_3(0, front);
}

polygon_3 build_3D_circle(const point center,
			  const double radius,
			  const point normal) {
  const rotation r = rotate_from_to(point(0, 0, 1), normal);

  polygon_3 circle = build_2D_circle(radius);
  circle = apply(r, circle);
  circle = shift(center, circle);

  return circle;
}

triangular_mesh build_hole_mesh(const point center,
				const point normal,
				const double depth,
				const double radius) {
  polygon_3 circle = build_3D_circle(center, radius, normal);
  return extrude(circle, depth*normal);
}

void vtk_debug_nef(const Nef_polyhedron& n) {
  vtk_debug_meshes(nef_polyhedron_to_trimeshes(n));
}

std::pair<Nef_polyhedron, Nef_polyhedron>
insert_attachment_holes(const Nef_polyhedron& clipped_pos,
			const Nef_polyhedron& clipped_neg,
			const plane active_plane) {
  triangular_mesh hole_mesh =
    build_hole_mesh(point(0, 0, 0), -1*active_plane.normal(), 10.0, 0.1);

  vtk_debug_mesh(hole_mesh);<commit_msg>I can now compute the set of facets on each resultant mesh that are coplanar to the slice plane<commit_after>#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

#include "geometry/extrusion.h"
#include "geometry/vtk_utils.h"
#include "geometry/vtk_debug.h"
#include "process_planning/surface_planning.h"
#include "system/parse_stl.h"

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QHBoxLayout>

using namespace gca;

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
{

  current_mode = SLICE_MODE;

  vtk_window = new QVTKWidget(this, Qt::Widget);

  QHBoxLayout *layout = new QHBoxLayout;

  QPushButton* button2 = new QPushButton("Load STL");
  accept_button = new QPushButton("Accept slice", this);
  reject_button = new QPushButton("Reject slice", this);
  set_done_button = new QPushButton("Done with part", this);

  QVBoxLayout* update_buttons = new QVBoxLayout();
  update_buttons->addWidget(button2);
  update_buttons->addWidget(accept_button);
  update_buttons->addWidget(reject_button);
  update_buttons->addWidget(set_done_button);

  in_progress_heading = new QLabel();
  in_progress_heading->setText("In Progress");

  QVBoxLayout* in_progress = new QVBoxLayout();
  in_progress->addWidget(in_progress_heading);

  QLabel* completed_heading = new QLabel();
  completed_heading->setText("Completed");

  QVBoxLayout* completed = new QVBoxLayout();
  completed->addWidget(completed_heading);

  layout->addLayout(update_buttons);
  layout->addWidget(vtk_window);
  layout->addLayout(in_progress);
  layout->addLayout(completed);

  setCentralWidget(new QWidget);
  centralWidget()->setLayout(layout);

  connect(accept_button, SIGNAL (released()), this, SLOT (handle_accept()));
  connect(reject_button, SIGNAL (released()), this, SLOT (handle_reject()));
  connect(set_done_button, SIGNAL (released()), this, SLOT (handle_set_done()));

  // active_mesh =
  //   parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/artusitestp1 - Part 1.stl", 0.0001);
  
  active_mesh =
    parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/caliperbedlevelingi3v2_fixed - Part 1.stl", 0.0001);

  //parse_stl("/Users/dillon/CppWorkspace/gca/test/stl-files/onshape_parts/SmallReverseCameraMount - Part 1.stl", 0.0001);

  slice_planes = possible_slice_planes(active_mesh);

  DBG_ASSERT(slice_planes.size() > 0);

  active_plane = slice_planes.back();
  slice_planes.pop_back();

  active_plane_actor = plane_actor(vtk_plane(active_plane));

  active_mesh_polydata = polydata_for_trimesh(active_mesh);
  color_polydata(active_mesh_polydata, 0, 255, 0);

  vtkSmartPointer<vtkPolyDataMapper> mapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputData(active_mesh_polydata);

  active_mesh_actor = 
    vtkSmartPointer<vtkActor>::New();
  active_mesh_actor->SetMapper(mapper);

  renderer = vtkSmartPointer<vtkRenderer>::New();

  renderer->SetBackground(1, 1, 1);
  renderer->AddActor(active_mesh_actor);
  renderer->AddActor(active_plane_actor);

  vtk_window->GetRenderWindow()->AddRenderer(renderer);

  vtk_window->show();

}

polygon_3 build_2D_circle(const double radius) {
  // typedef boost::geometry::model::d2::point_xy<double> point;
  // typedef boost::geometry::model::polygon<point> polygon;

  // Declare the point_circle strategy
  boost::geometry::strategy::buffer::point_circle point_strategy(360);

  // Declare other strategies
  boost::geometry::strategy::buffer::distance_symmetric<double> distance_strategy(radius);
  boost::geometry::strategy::buffer::join_round join_strategy;
  boost::geometry::strategy::buffer::end_round end_strategy;
  boost::geometry::strategy::buffer::side_straight side_strategy;

  // Declare/fill of a multi point
  boost::geometry::model::multi_point<boost_point_2> mp;
  boost::geometry::read_wkt("MULTIPOINT((0 0))", mp); //,(3 4),(4 4),(7 3))", mp);

  // Create the buffer of a multi point
  boost_multipoly_2 result;
  boost::geometry::buffer(mp, result,
			  distance_strategy, side_strategy,
			  join_strategy, end_strategy, point_strategy);

  DBG_ASSERT(result.size() == 1);

  boost_poly_2 front = result.front();

  return to_polygon_3(0, front);
}

polygon_3 build_3D_circle(const point center,
			  const double radius,
			  const point normal) {
  const rotation r = rotate_from_to(point(0, 0, 1), normal);

  polygon_3 circle = build_2D_circle(radius);
  circle = apply(r, circle);
  circle = shift(center, circle);

  return circle;
}

triangular_mesh build_hole_mesh(const point center,
				const point normal,
				const double depth,
				const double radius) {
  polygon_3 circle = build_3D_circle(center, radius, normal);
  return extrude(circle, depth*normal);
}

void vtk_debug_nef(const Nef_polyhedron& n) {
  vtk_debug_meshes(nef_polyhedron_to_trimeshes(n));
}

std::vector<index_t> coplanar_facets(const plane p,
				     const triangular_mesh& m) {
  vector<index_t> inds;
  for (auto& i : m.face_indexes()) {
    triangle t = m.face_triangle(i);
    point pt = t.v1;
    point diff = pt - p.pt();
    if (angle_eps(p.normal(), diff, 90.0, 1.0) &&
	(angle_eps(normal(t), p.normal(), 0.0, 1.0) ||
	 angle_eps(normal(t), p.normal(), 180.0, 1.0))) {
      inds.push_back(i);
    }
  }
  return inds;
}

point
hole_position(const Nef_polyhedron& clipped_pos,
	      const Nef_polyhedron& clipped_neg,
	      const plane active_plane) {
  auto pos_mesh = nef_to_single_trimesh(clipped_pos);
  auto neg_mesh = nef_to_single_trimesh(clipped_neg);

  // Q: How do you merge surfaces? Which surfaces need to
  // be joined by bolts?

  vector<index_t> pos_plane_tris =
    coplanar_facets(active_plane, pos_mesh);

  vtk_debug_highlight_inds(pos_plane_tris, pos_mesh);

  vector<index_t> neg_plane_tris =
    coplanar_facets(active_plane, neg_mesh);

  vtk_debug_highlight_inds(neg_plane_tris, neg_mesh);

  return point(0, 0, 0);
}

std::pair<Nef_polyhedron, Nef_polyhedron>
insert_attachment_holes(const Nef_polyhedron& clipped_pos,
			const Nef_polyhedron& clipped_neg,
			const plane active_plane) {
  point pos = hole_position(clipped_pos, clipped_neg, active_plane);
  triangular_mesh hole_mesh =
    build_hole_mesh(pos, -1*active_plane.normal(), 10.0, 0.1);

  vtk_debug_mesh(hole_mesh);
{'fraction_non_alphanumeric': 0.12723779582569208, 'fraction_numerical': 0.013623264343725438, 'mean_word_length': 5.808561236623068, 'pattern_counts': {'":': 0, '<': 35, '<?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': '870908', 'n_tokens_mistral': 4216, 'n_tokens_neox': 3942, 'n_words': 703}