Gestion des surfaces et géométrie dans le moteur de tranchage BambuStudio

L'en-tête Surface.hpp constitue une brique fondamentale du moteur de tranchage (slicer) de BambuStudio. Il définit la structure des données nécessaires à la classification des surfaces, à la gestion de la géométrie des couches et aux stratégies de remplissage. Cette analyse technique détaille les structures de données et les algorithmes de traitement de surface.

Classification des types de surfaces

L'énumération SurfaceType permet de segmenter les polygones d'une couche selon leur rôle fonctionnel dans l'impression 3D. Cette distinction est cruciale pour appliquer des paramètres de vitesse, de refroidissement et de débit spécifiques.

enum class SurfaceType {
    Top,              // Surface horizontale supérieure
    Bottom,           // Surface inférieure en contact avec le support ou le plateau
    BottomBridge,     // Surface inférieure en porte-à-faux (pontage)
    Internal,         // Remplissage partiel (sparse infill)
    InternalSolid,    // Remplissage plein interne
    InternalBridge,   // Pontage interne
    InternalVoid,     // Zones vides ou cavités
    Perimeter,        // Zones dédiées aux parois
    TotalCount        // Marqueur pour la taille de l'énumération
};

La classe Surface

La classe Surface encapsule la géométrie complexe (incluant les îlots et les trous) ainsi que les métadonnées de fabrication associées à une région spécifique d'une couche.

class Surface {
public:
    SurfaceType   role;             // Type de la surface
    ExPolygon     geometry;         // Structure géométrique (contour + trous)
    double        thickness_mm;     // Épaisseur physique en millimètres
    uint16_t      layer_span;       // Nombre de couches couvertes
    double        bridge_flow_ratio;// Ratio de flux pour les pontages
    uint16_t      additional_walls; // Parois supplémentaires requises

    // Vérifications d'état
    bool is_top_layer() const { return role == SurfaceType::Top; }
    bool is_bridge_structure() const { 
        return role == SurfaceType::BottomBridge || role == SurfaceType::InternalBridge; 
    }
    double get_area() const { return geometry.area(); }
};

Méthodes de transformation géométrique

Le traitement des surfaces nécessite souvent de convertir des objets Surface complexes en listes de polygones simples pour les opérations booléennes ou la génération de trajectoires G-code.

Conversion en polygones simples

inline Polygons flatten_to_polygons(const Surfaces &input_surfaces) {
    Polygons results;
    for (const auto &surface : input_surfaces) {
        results.push_back(surface.geometry.contour);
        for (const auto &hole : surface.geometry.holes) {
            results.push_back(hole);
        }
    }
    return results;
}

Conversion avec transfert de propriété

Pour optimiser les performances, l'utilisation de la sémantique de mouvement (move semantics) est privilégiée lors du transfert de données géométriques lourdes.

inline ExPolygons move_to_expolygons(Surfaces &&input_surfaces) {
    ExPolygons results;
    results.reserve(input_surfaces.size());
    for (auto &surface : input_surfaces) {
        results.emplace_back(std::move(surface.geometry));
    }
    return results;
}

Logique de fusion et d'agrégation

Afin de réduire la complexité du calcul des trajectoires, les surfaces adjacentes partageant les mêmes propriétés physiques peuvent être fusionnées.

bool check_merging_compatibility(const Surface &surface_a, const Surface &surface_b) {
    return surface_a.role == surface_b.role && 
           std::abs(surface_a.thickness_mm - surface_b.thickness_mm) < 1e-4 &&
           surface_a.bridge_flow_ratio == surface_b.bridge_flow_ratio;
}

inline void append_surface_regions(Surfaces &target, ExPolygons &&new_regions, SurfaceType role) {
    for (auto &poly : new_regions) {
        target.emplace_back(Surface(role, std::move(poly)));
    }
}

Utilitaires et Analyse Spatiale

Le moteur intègre des outils pour calculer l'emprise spatiale des surfaces, facilitant ainsi la planifictaion des mouvements de la tête d'impression.

BoundingBox compute_total_bounds(const Surfaces &surfaces) {
    BoundingBox boundary;
    for (const auto &s : surfaces) {
        boundary.merge(get_extents(s.geometry));
    }
    return boundary;
}

Optimisation et Performance

La conception de ce module repose sur plusieurs principes d'optimisation logicielle :

  • Gestion mémoire : Utilisation intensive de std::move et emplace_back pour minimiser les allocations sur le tas et les copies de vecteurs de points.
  • Complexité algorithmique : Les tests de type de surface sont effectués en temps constant O(1), tandis que les conversions géométriques suivent une complexité linéaire O(n) par rapport au nombre de sommets.
  • Pré-allocation : L'utilisation de reserve() sur les conteneurs réduit la fragmentation mémoire lors du traitement de modèles 3D complexes comportant des milliers de facettes.
Opération Complexité Temporelle Usage Mémoire
Identification du type O(1) Minimal
Calcul de l'aire O(n) O(1)
Fusion de surfaces O(1) par paire O(1)
Conversion ExPolygon O(n) O(n)

Ce système de gestion des surfaces permet à BambuStudio d'isoler efficacement les régions critiqeus d'un objet (comme les pontages ou les couches de finition) afin d'appliquer des algorithmes de génération de remplissage et de parois hautement spécialisés.

Étiquettes: BambuStudio computational-geometry C++ Slicing-Engine 3D-Printing

Publié le 3 octobre à 09h38