diff --git a/source/shapes/png_shape.cpp b/source/shapes/png_shape.cpp index cc29ed7..db029f8 100644 --- a/source/shapes/png_shape.cpp +++ b/source/shapes/png_shape.cpp @@ -101,26 +101,65 @@ void PNGShape::generatePoints(int num_points, float screen_width, float screen_h // Generar puntos según el enfoque configurado generateExtrudedPoints(); - // Calcular cuántos puntos 3D se necesitan + // Calcular cuántos puntos 2D se necesitan size_t num_2d_points = PNG_USE_EDGES_ONLY ? edge_points_.size() : filled_points_.size(); size_t total_3d_points = num_2d_points * num_layers_; - // ADAPTACIÓN AUTOMÁTICA: Si hay muy pocas pelotas, cambiar a bordes - if (!PNG_USE_EDGES_ONLY && num_points < static_cast(total_3d_points) / 2) { - std::cout << "[PNG_SHAPE] Advertencia: Solo " << num_points << " pelotas para " - << total_3d_points << " puntos (relleno).\n"; - std::cout << "[PNG_SHAPE] Cambiando automáticamente a BORDES para mejor visualización.\n"; + // === ADAPTACIÓN AUTOMÁTICA MULTINIVEL === - // Regenerar solo con bordes + // Nivel 1: Si relleno completo y pocas pelotas → switch a bordes + if (!PNG_USE_EDGES_ONLY && num_points < static_cast(total_3d_points) / 2) { + std::cout << "[PNG_SHAPE] Paso 1: Cambiando de RELLENO a BORDES (pelotas insuficientes)\n"; detectEdges(); num_2d_points = edge_points_.size(); total_3d_points = num_2d_points * num_layers_; } + // Nivel 2: Reducir capas de extrusión si aún hay pocas pelotas + while (num_layers_ > 1 && num_points < static_cast(total_3d_points) / 2) { + num_layers_ = std::max(1, num_layers_ / 2); // Dividir capas a la mitad + total_3d_points = num_2d_points * num_layers_; + std::cout << "[PNG_SHAPE] Paso 2: Reduciendo capas a " << num_layers_ + << " (total puntos: " << total_3d_points << ")\n"; + } + + // Nivel 3: Sampling de píxeles (tomar cada N píxeles) si aún insuficiente + int sampling_step = 1; + std::vector* points_to_sample = (!edge_points_.empty()) ? &edge_points_ : &filled_points_; + + while (sampling_step < 10 && num_points < static_cast(total_3d_points) / 2) { + sampling_step++; + + // Aplicar sampling (tomar cada N puntos) + std::vector sampled_points; + for (size_t i = 0; i < points_to_sample->size(); i += sampling_step) { + sampled_points.push_back((*points_to_sample)[i]); + } + + if (!sampled_points.empty()) { + *points_to_sample = sampled_points; + num_2d_points = points_to_sample->size(); + total_3d_points = num_2d_points * num_layers_; + std::cout << "[PNG_SHAPE] Paso 3: Aplicando sampling 1/" << sampling_step + << " (puntos: " << num_2d_points << ")\n"; + } + } + // Debug: mostrar configuración final - std::cout << "[PNG_SHAPE] Modo: " << (PNG_USE_EDGES_ONLY ? "BORDES" : "RELLENO") << "\n"; - std::cout << "[PNG_SHAPE] Detectados " << num_2d_points << " puntos 2D × " - << num_layers_ << " capas = " << total_3d_points << " puntos 3D totales\n"; + std::cout << "[PNG_SHAPE] === CONFIGURACIÓN FINAL ===\n"; + std::string mode_str = (!edge_points_.empty()) ? "BORDES" : (PNG_USE_EDGES_ONLY ? "BORDES" : "RELLENO"); + std::cout << "[PNG_SHAPE] Modo: " << mode_str; + if (sampling_step > 1) { + std::cout << " (optimizado)"; + } + std::cout << "\n"; + std::cout << "[PNG_SHAPE] Píxeles 2D: " << num_2d_points; + if (sampling_step > 1) { + std::cout << " (sampling 1/" << sampling_step << ")"; + } + std::cout << "\n"; + std::cout << "[PNG_SHAPE] Capas: " << num_layers_ << "\n"; + std::cout << "[PNG_SHAPE] Total puntos 3D: " << total_3d_points << "\n"; std::cout << "[PNG_SHAPE] Pelotas disponibles: " << num_points << "\n"; std::cout << "[PNG_SHAPE] Ratio: " << (float)num_points / (float)total_3d_points << " pelotas/punto\n";