mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-16 13:32:44 +00:00
138 lines
5.3 KiB
C++
138 lines
5.3 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
struct indexed_triangle_set;
|
|
|
|
namespace Slic3r {
|
|
|
|
class TriangleMesh;
|
|
class ModelVolume;
|
|
|
|
struct TextureImage {
|
|
int width = 0;
|
|
int height = 0;
|
|
int channels = 4;
|
|
std::vector<unsigned char> data;
|
|
};
|
|
|
|
struct TexturedMesh {
|
|
std::vector<std::array<float,3>> vertices;
|
|
std::vector<std::array<int,3>> indices;
|
|
std::vector<std::array<float,2>> uvs;
|
|
std::vector<TextureImage> textures;
|
|
std::vector<int> material_ids;
|
|
// material index -> index in textures[] (-1 if no texture, use material_colors)
|
|
std::vector<int> material_texture_map;
|
|
// per-material baseColorFactor (RGBA 0-1), indexed by material index
|
|
std::vector<std::array<float,4>> material_colors;
|
|
|
|
// Per-face independent UV support (for OBJ where the same vertex can have
|
|
// different texture coordinates on different faces).
|
|
std::vector<std::array<float,2>> uv_coords; // UV coordinate pool
|
|
std::vector<std::array<int,3>> uv_indices; // per-face UV indices into uv_coords
|
|
|
|
bool has_face_uvs() const { return !uv_indices.empty() && !uv_coords.empty(); }
|
|
|
|
// Pre-computed per-face colors (e.g. from OBJ vertex colors or MTL Kd).
|
|
// When non-empty, the pipeline skips texture decode/sample/oversample and
|
|
// consumes these instead of sampling a texture.
|
|
// Each entry is {R, G, B} in [0..255].
|
|
std::vector<std::array<std::size_t,3>> precomputed_face_colors;
|
|
|
|
// Per-vertex colors from OBJ (RGBA, [0..1]), indexed by vertex index.
|
|
// On a low-poly mesh these are quantized into a small palette and the mesh is
|
|
// split along the resulting cluster boundaries, so color borders stay sharp
|
|
// instead of being averaged away into a single color per face.
|
|
std::vector<std::array<float,4>> precomputed_vertex_colors;
|
|
};
|
|
|
|
struct PaintedMesh {
|
|
std::vector<std::array<float,3>> vertices;
|
|
std::vector<std::array<int,3>> indices;
|
|
std::vector<std::array<std::size_t,3>> face_colors; // per-face RGB [0..255]
|
|
std::vector<std::array<std::size_t,3>> cluster_colors;
|
|
};
|
|
|
|
using PaintProgressCallback = std::function<void(int percent, const char* message)>;
|
|
using PaintCancelCallback = std::function<bool()>;
|
|
using PaintMeshRepairCallback = std::function<bool(const indexed_triangle_set& mesh,
|
|
indexed_triangle_set& repaired_mesh,
|
|
std::function<void(const char* message, unsigned progress)> progress_callback,
|
|
std::function<bool()> cancel_callback,
|
|
std::string* error_message)>;
|
|
|
|
struct TexturePaintingSettings {
|
|
std::size_t target_colors_num = 4;
|
|
double smooth_weight = 0.5;
|
|
std::size_t oversampling_iters = 0;
|
|
enum class MeshRepairDecision {
|
|
Ask,
|
|
ImportWithoutRepair,
|
|
RepairAndImport
|
|
};
|
|
MeshRepairDecision mesh_repair_decision = MeshRepairDecision::ImportWithoutRepair;
|
|
bool* mesh_repair_decision_required = nullptr;
|
|
PaintMeshRepairCallback mesh_repair_callback;
|
|
};
|
|
|
|
struct FilamentMatch {
|
|
int cluster_index = -1;
|
|
int filament_index = -1;
|
|
double delta_e = 0.0;
|
|
std::array<std::size_t,3> cluster_color = {0,0,0};
|
|
std::array<float,4> filament_color = {0,0,0,1};
|
|
};
|
|
|
|
bool texture_to_painting(
|
|
const TexturedMesh& textured,
|
|
PaintedMesh& painted,
|
|
const TexturePaintingSettings& settings = {},
|
|
PaintProgressCallback progress = nullptr,
|
|
PaintCancelCallback cancel = nullptr);
|
|
// Turn pre-computed per-face colors into a painted mesh, skipping texture decode
|
|
// and UV sampling. A low-poly mesh that also carries precomputed_vertex_colors is
|
|
// split along quantized color boundaries, which replaces its geometry.
|
|
bool face_colors_to_painting(
|
|
const TexturedMesh& mesh,
|
|
PaintedMesh& painted,
|
|
const TexturePaintingSettings& settings = {},
|
|
PaintProgressCallback progress = nullptr,
|
|
PaintCancelCallback cancel = nullptr);
|
|
|
|
|
|
std::vector<FilamentMatch> match_clusters_to_filaments(
|
|
const std::vector<std::array<std::size_t,3>>& cluster_colors,
|
|
const std::vector<std::array<float,4>>& filament_colors,
|
|
const std::vector<std::string>& filament_names);
|
|
|
|
double compute_delta_e(
|
|
const std::array<std::size_t,3>& rgb1,
|
|
const std::array<float,4>& rgba2);
|
|
|
|
bool apply_painted_mesh_to_volume(
|
|
const PaintedMesh& painted,
|
|
const std::vector<FilamentMatch>& matches,
|
|
ModelVolume& volume);
|
|
|
|
// Decode a TextureImage (which may contain raw PNG/JPEG bytes) into BGR pixel data.
|
|
// On success, populates out_pixels (BGR, 3 bytes/pixel) and sets out_w/out_h.
|
|
bool decode_texture_to_pixels(
|
|
const TextureImage& img,
|
|
std::vector<unsigned char>& out_pixels,
|
|
int& out_w, int& out_h);
|
|
|
|
// Sample per-face colors from the correct texture per material_ids.
|
|
// Uses material_texture_map / material_colors for multi-material GLBs.
|
|
// Falls back to textures[0] when the mapping is absent.
|
|
bool sample_original_face_colors(
|
|
const TexturedMesh& textured,
|
|
std::vector<std::array<std::size_t,3>>& out_face_colors);
|
|
|
|
} // namespace Slic3r
|