bool mergeUserInputIntoScene()

in src/simulator/image_to_box2d.cpp [328:393]


bool mergeUserInputIntoScene(const ::scene::UserInput& userInput,
                             const std::vector<Body>& sceneBodies,
                             bool keepSpaceAroundBodies, bool allowOcclusions,
                             int height, int width, std::vector<Body>* bodies) {
  bool good = true;
  // 1. Adding balls.
  for (const ::scene::CircleWithPosition& ball : userInput.balls) {
    bool hasOcclusions = false;
    for (const Body& sceneBody : sceneBodies) {
      if (doesBallOccludeBody(ball, sceneBody)) {
        hasOcclusions = true;
        good = false;
        break;
      }
    }
    if (!hasOcclusions || allowOcclusions) {
      bodies->push_back(
          buildCircle(ball.position.x, ball.position.y, ball.radius));
    }
  }

  // 2. Adding polygons.
  const auto num_balls = bodies->size();
  for (const ::scene::AbsoluteConvexPolygon& polygon : userInput.polygons) {
    if (!geometry::isConvexPositivePolygon(polygon.vertices)) {
      good = false;
      continue;
    }
    // Need to check both scene bodies and just added balls.
    bool hasOcclusions = false;
    for (int i = 0; i < sceneBodies.size() + num_balls; ++i) {
      const Body& sceneBody = (i < sceneBodies.size())
                                  ? sceneBodies[i]
                                  : (*bodies)[i - sceneBodies.size()];
      if (doesPolygonOccludeBody(polygon, sceneBody)) {
        hasOcclusions = true;
        good = false;
        break;
      }
    }
    if (!hasOcclusions || allowOcclusions) {
      bodies->push_back(absolutePolygonToBody(polygon));
    }
  }

  // 3. Vectorizing and adding points.
  if (userInput.flattened_point_list.empty()) {
    return good;
  }
  if (userInput.flattened_point_list.size() % 2 != 0) {
    throw std::runtime_error(
        "Number of elements in flattened_point_list must be even.");
  }
  std::vector<IntVector> input_points(userInput.flattened_point_list.size() /
                                      2);
  for (int i = 0; i < input_points.size(); ++i) {
    input_points[i].x = userInput.flattened_point_list[2 * i];
    input_points[i].y = userInput.flattened_point_list[2 * i + 1];
  }
  const std::vector<IntVector> goodInputPoints =
      filterPointsOutsideCanvass(input_points, height, width);
  good = good && (goodInputPoints.size() == input_points.size());

  // TODO: re-implement free draw input without opencv.
  return good;
}