mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	AppController integration
This commit is contained in:
		
							parent
							
								
									5446b9f1e5
								
							
						
					
					
						commit
						ad4d95f60c
					
				
					 17 changed files with 1435 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -19,6 +19,7 @@ use Wx::Locale gettext => 'L';
 | 
			
		|||
our $qs_last_input_file;
 | 
			
		||||
our $qs_last_output_file;
 | 
			
		||||
our $last_config;
 | 
			
		||||
our $appController;
 | 
			
		||||
 | 
			
		||||
# Events to be sent from a C++ Tab implementation:
 | 
			
		||||
# 1) To inform about a change of a configuration value.
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +32,9 @@ sub new {
 | 
			
		|||
    
 | 
			
		||||
    my $self = $class->SUPER::new(undef, -1, $Slic3r::FORK_NAME . ' - ' . $Slic3r::VERSION, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE);
 | 
			
		||||
    Slic3r::GUI::set_main_frame($self);
 | 
			
		||||
    
 | 
			
		||||
    $appController = Slic3r::AppController->new();
 | 
			
		||||
 | 
			
		||||
    if ($^O eq 'MSWin32') {
 | 
			
		||||
        # Load the icon either from the exe, or from the ico file.
 | 
			
		||||
        my $iconfile = Slic3r::decode_path($FindBin::Bin) . '\slic3r.exe';
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +66,15 @@ sub new {
 | 
			
		|||
    $self->{statusbar}->SetStatusText(L("Version ").$Slic3r::VERSION.L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"));
 | 
			
		||||
    $self->SetStatusBar($self->{statusbar});
 | 
			
		||||
    
 | 
			
		||||
    # Make the global status bar and its progress indicator available in C++
 | 
			
		||||
    $appController->set_global_progress_indicator(
 | 
			
		||||
        $self->{statusbar}->{prog}->GetId(),
 | 
			
		||||
        $self->{statusbar}->GetId(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    $appController->set_model($self->{plater}->{model});
 | 
			
		||||
    $appController->set_print($self->{plater}->{print});
 | 
			
		||||
 | 
			
		||||
    $self->{loaded} = 1;
 | 
			
		||||
    
 | 
			
		||||
    # initialize layout
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -240,6 +240,10 @@ add_library(libslic3r_gui STATIC
 | 
			
		|||
    ${LIBDIR}/slic3r/Utils/PresetUpdater.hpp
 | 
			
		||||
    ${LIBDIR}/slic3r/Utils/Time.cpp
 | 
			
		||||
    ${LIBDIR}/slic3r/Utils/Time.hpp
 | 
			
		||||
    ${LIBDIR}/slic3r/IProgressIndicator.hpp
 | 
			
		||||
    ${LIBDIR}/slic3r/AppController.hpp
 | 
			
		||||
    ${LIBDIR}/slic3r/AppController.cpp
 | 
			
		||||
    ${LIBDIR}/slic3r/AppControllerWx.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(admesh STATIC
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -142,6 +142,9 @@ inline void ShapeLike::offset(PolygonImpl& sh, TCoord<PointImpl> distance) {
 | 
			
		|||
    using ClipperLib::etClosedPolygon;
 | 
			
		||||
    using ClipperLib::Paths;
 | 
			
		||||
 | 
			
		||||
    // If the input is not at least a triangle, we can not do this algorithm
 | 
			
		||||
    if(sh.Contour.size() <= 3) throw GeometryException(GeoErr::OFFSET);
 | 
			
		||||
 | 
			
		||||
    ClipperOffset offs;
 | 
			
		||||
    Paths result;
 | 
			
		||||
    offs.AddPath(sh.Contour, jtMiter, etClosedPolygon);
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +154,8 @@ inline void ShapeLike::offset(PolygonImpl& sh, TCoord<PointImpl> distance) {
 | 
			
		|||
    // it removes the last vertex as well so boost will not have a closed
 | 
			
		||||
    // polygon
 | 
			
		||||
 | 
			
		||||
    assert(result.size() == 1);
 | 
			
		||||
    if(result.size() != 1) throw GeometryException(GeoErr::OFFSET);
 | 
			
		||||
 | 
			
		||||
    sh.Contour = result.front();
 | 
			
		||||
 | 
			
		||||
    // recreate closed polygon
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,5 +205,36 @@ inline Radians::Radians(const Degrees °s): Double( degs * Pi/180) {}
 | 
			
		|||
 | 
			
		||||
inline double Radians::toDegrees() { return operator Degrees(); }
 | 
			
		||||
 | 
			
		||||
enum class GeoErr : std::size_t {
 | 
			
		||||
    OFFSET,
 | 
			
		||||
    MERGE,
 | 
			
		||||
    NFP
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const std::string ERROR_STR[] = {
 | 
			
		||||
    "Offsetting could not be done! An invalid geometry may have been added."
 | 
			
		||||
    "Error while merging geometries!"
 | 
			
		||||
    "No fit polygon cannaot be calculated."
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GeometryException: public std::exception {
 | 
			
		||||
 | 
			
		||||
    virtual const char * errorstr(GeoErr errcode) const {
 | 
			
		||||
        return ERROR_STR[static_cast<std::size_t>(errcode)].c_str();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GeoErr errcode_;
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    GeometryException(GeoErr code): errcode_(code) {}
 | 
			
		||||
 | 
			
		||||
    GeoErr errcode() const { return errcode_; }
 | 
			
		||||
 | 
			
		||||
    virtual const char * what() const override {
 | 
			
		||||
        return errorstr(errcode_);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif // LIBNEST2D_CONFIG_HPP
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -648,6 +648,8 @@ public:
 | 
			
		|||
 | 
			
		||||
    using IndexedPackGroup = _IndexedPackGroup<typename Item::ShapeType>;
 | 
			
		||||
    using PackGroup = _PackGroup<typename Item::ShapeType>;
 | 
			
		||||
    using ResultType = PackGroup;
 | 
			
		||||
    using ResultTypeIndexed = IndexedPackGroup;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    BinType bin_;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,10 +74,370 @@ void arrangeRectangles() {
 | 
			
		|||
//        {{0, 0}, {0, 20*SCALE}, {10*SCALE, 0}, {0, 0}}
 | 
			
		||||
//    };
 | 
			
		||||
 | 
			
		||||
    std::vector<Item> crasher = {
 | 
			
		||||
        {
 | 
			
		||||
            {-10836093, -2542602},
 | 
			
		||||
            {-10834392, -1849197},
 | 
			
		||||
            {-10826793, 1172203},
 | 
			
		||||
            {-10824993, 1884506},
 | 
			
		||||
            {-10823291, 2547500},
 | 
			
		||||
            {-10822994, 2642700},
 | 
			
		||||
            {-10807392, 2768295},
 | 
			
		||||
            {-10414295, 3030403},
 | 
			
		||||
            {-9677799, 3516204},
 | 
			
		||||
            {-9555896, 3531204},
 | 
			
		||||
            {-9445194, 3534698},
 | 
			
		||||
            {9353008, 3487297},
 | 
			
		||||
            {9463504, 3486999},
 | 
			
		||||
            {9574008, 3482902},
 | 
			
		||||
            {9695903, 3467399},
 | 
			
		||||
            {10684803, 2805702},
 | 
			
		||||
            {10814098, 2717803},
 | 
			
		||||
            {10832805, 2599502},
 | 
			
		||||
            {10836200, 2416801},
 | 
			
		||||
            {10819705, -2650299},
 | 
			
		||||
            {10800403, -2772300},
 | 
			
		||||
            {10670505, -2859596},
 | 
			
		||||
            {9800403, -3436599},
 | 
			
		||||
            {9678203, -3516197},
 | 
			
		||||
            {9556308, -3531196},
 | 
			
		||||
            {9445903, -3534698},
 | 
			
		||||
            {9084011, -3533798},
 | 
			
		||||
            {-9234294, -3487701},
 | 
			
		||||
            {-9462894, -3486999},
 | 
			
		||||
            {-9573497, -3483001},
 | 
			
		||||
            {-9695392, -3467300},
 | 
			
		||||
            {-9816898, -3387199},
 | 
			
		||||
            {-10429492, -2977798},
 | 
			
		||||
            {-10821193, -2714096},
 | 
			
		||||
            {-10836200, -2588195},
 | 
			
		||||
            {-10836093, -2542602},
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            {-3533699, -9084051},
 | 
			
		||||
            {-3487197, 9352449},
 | 
			
		||||
            {-3486797, 9462949},
 | 
			
		||||
            {-3482795, 9573547},
 | 
			
		||||
            {-3467201, 9695350},
 | 
			
		||||
            {-3386997, 9816949},
 | 
			
		||||
            {-2977699, 10429548},
 | 
			
		||||
            {-2713897, 10821249},
 | 
			
		||||
            {-2587997, 10836149},
 | 
			
		||||
            {-2542396, 10836149},
 | 
			
		||||
            {-2054698, 10834949},
 | 
			
		||||
            {2223503, 10824150},
 | 
			
		||||
            {2459800, 10823547},
 | 
			
		||||
            {2555002, 10823247},
 | 
			
		||||
            {2642601, 10822948},
 | 
			
		||||
            {2768301, 10807350},
 | 
			
		||||
            {3030302, 10414247},
 | 
			
		||||
            {3516099, 9677850},
 | 
			
		||||
            {3531002, 9555850},
 | 
			
		||||
            {3534502, 9445247},
 | 
			
		||||
            {3534301, 9334949},
 | 
			
		||||
            {3487300, -9353052},
 | 
			
		||||
            {3486904, -9463548},
 | 
			
		||||
            {3482801, -9574148},
 | 
			
		||||
            {3467302, -9695848},
 | 
			
		||||
            {2805601, -10684751},
 | 
			
		||||
            {2717802, -10814149},
 | 
			
		||||
            {2599403, -10832952},
 | 
			
		||||
            {2416801, -10836149},
 | 
			
		||||
            {-2650199, -10819749},
 | 
			
		||||
            {-2772197, -10800451},
 | 
			
		||||
            {-2859397, -10670450},
 | 
			
		||||
            {-3436401, -9800451},
 | 
			
		||||
            {-3515998, -9678350},
 | 
			
		||||
            {-3530998, -9556451},
 | 
			
		||||
            {-3534500, -9445848},
 | 
			
		||||
            {-3533699, -9084051},
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            {-3533798, -9084051},
 | 
			
		||||
            {-3487697, 9234249},
 | 
			
		||||
            {-3486999, 9462949},
 | 
			
		||||
            {-3482997, 9573547},
 | 
			
		||||
            {-3467296, 9695350},
 | 
			
		||||
            {-3387199, 9816949},
 | 
			
		||||
            {-2977798, 10429548},
 | 
			
		||||
            {-2714096, 10821249},
 | 
			
		||||
            {-2588199, 10836149},
 | 
			
		||||
            {-2542594, 10836149},
 | 
			
		||||
            {-2054798, 10834949},
 | 
			
		||||
            {2223701, 10824150},
 | 
			
		||||
            {2459903, 10823547},
 | 
			
		||||
            {2555202, 10823247},
 | 
			
		||||
            {2642704, 10822948},
 | 
			
		||||
            {2768302, 10807350},
 | 
			
		||||
            {3030403, 10414247},
 | 
			
		||||
            {3516204, 9677850},
 | 
			
		||||
            {3531204, 9555850},
 | 
			
		||||
            {3534702, 9445247},
 | 
			
		||||
            {3487300, -9353052},
 | 
			
		||||
            {3486999, -9463548},
 | 
			
		||||
            {3482902, -9574148},
 | 
			
		||||
            {3467403, -9695848},
 | 
			
		||||
            {2805702, -10684751},
 | 
			
		||||
            {2717803, -10814149},
 | 
			
		||||
            {2599502, -10832952},
 | 
			
		||||
            {2416801, -10836149},
 | 
			
		||||
            {-2650299, -10819749},
 | 
			
		||||
            {-2772296, -10800451},
 | 
			
		||||
            {-2859596, -10670450},
 | 
			
		||||
            {-3436595, -9800451},
 | 
			
		||||
            {-3516197, -9678350},
 | 
			
		||||
            {-3531196, -9556451},
 | 
			
		||||
            {-3534698, -9445848},
 | 
			
		||||
            {-3533798, -9084051},
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            {-49433151, 4289947},
 | 
			
		||||
            {-49407352, 4421947},
 | 
			
		||||
            {-49355751, 4534446},
 | 
			
		||||
            {-29789449, 36223850},
 | 
			
		||||
            {-29737350, 36307445},
 | 
			
		||||
            {-29512149, 36401447},
 | 
			
		||||
            {-29089149, 36511646},
 | 
			
		||||
            {-28894351, 36550342},
 | 
			
		||||
            {-18984951, 37803447},
 | 
			
		||||
            {-18857151, 37815151},
 | 
			
		||||
            {-18271148, 37768947},
 | 
			
		||||
            {-18146148, 37755146},
 | 
			
		||||
            {-17365447, 37643947},
 | 
			
		||||
            {-17116649, 37601146},
 | 
			
		||||
            {11243545, 29732448},
 | 
			
		||||
            {29276451, 24568149},
 | 
			
		||||
            {29497543, 24486148},
 | 
			
		||||
            {29654548, 24410953},
 | 
			
		||||
            {31574546, 23132640},
 | 
			
		||||
            {33732849, 21695148},
 | 
			
		||||
            {33881950, 21584445},
 | 
			
		||||
            {34019454, 21471950},
 | 
			
		||||
            {34623153, 20939151},
 | 
			
		||||
            {34751945, 20816951},
 | 
			
		||||
            {35249244, 20314647},
 | 
			
		||||
            {36681549, 18775447},
 | 
			
		||||
            {36766548, 18680446},
 | 
			
		||||
            {36794250, 18647144},
 | 
			
		||||
            {36893951, 18521953},
 | 
			
		||||
            {37365951, 17881946},
 | 
			
		||||
            {37440948, 17779247},
 | 
			
		||||
            {37529243, 17642444},
 | 
			
		||||
            {42233245, 10012245},
 | 
			
		||||
            {42307250, 9884048},
 | 
			
		||||
            {42452949, 9626548},
 | 
			
		||||
            {44258949, 4766647},
 | 
			
		||||
            {48122245, -5990951},
 | 
			
		||||
            {48160751, -6117950},
 | 
			
		||||
            {49381546, -17083953},
 | 
			
		||||
            {49412246, -17420953},
 | 
			
		||||
            {49429450, -18011253},
 | 
			
		||||
            {49436141, -18702651},
 | 
			
		||||
            {49438949, -20087953},
 | 
			
		||||
            {49262947, -24000852},
 | 
			
		||||
            {49172546, -24522455},
 | 
			
		||||
            {48847549, -25859151},
 | 
			
		||||
            {48623847, -26705650},
 | 
			
		||||
            {48120246, -28514953},
 | 
			
		||||
            {48067146, -28699455},
 | 
			
		||||
            {48017845, -28862453},
 | 
			
		||||
            {47941543, -29096954},
 | 
			
		||||
            {47892547, -29246852},
 | 
			
		||||
            {47813545, -29466651},
 | 
			
		||||
            {47758453, -29612955},
 | 
			
		||||
            {47307548, -30803253},
 | 
			
		||||
            {46926544, -31807151},
 | 
			
		||||
            {46891448, -31899551},
 | 
			
		||||
            {46672546, -32475852},
 | 
			
		||||
            {46502449, -32914852},
 | 
			
		||||
            {46414451, -33140853},
 | 
			
		||||
            {46294250, -33447650},
 | 
			
		||||
            {46080146, -33980255},
 | 
			
		||||
            {46039245, -34071853},
 | 
			
		||||
            {45970542, -34186653},
 | 
			
		||||
            {45904243, -34295955},
 | 
			
		||||
            {45786247, -34475650},
 | 
			
		||||
            {43063247, -37740955},
 | 
			
		||||
            {42989547, -37815151},
 | 
			
		||||
            {12128349, -36354953},
 | 
			
		||||
            {12101844, -36343955},
 | 
			
		||||
            {11806152, -36217453},
 | 
			
		||||
            {7052848, -34171649},
 | 
			
		||||
            {-3234352, -29743150},
 | 
			
		||||
            {-15684650, -24381851},
 | 
			
		||||
            {-16573852, -23998851},
 | 
			
		||||
            {-20328948, -22381254},
 | 
			
		||||
            {-20383052, -22357254},
 | 
			
		||||
            {-20511447, -22280651},
 | 
			
		||||
            {-42221252, -8719951},
 | 
			
		||||
            {-42317150, -8653255},
 | 
			
		||||
            {-42457851, -8528949},
 | 
			
		||||
            {-42600151, -8399852},
 | 
			
		||||
            {-47935852, -2722949},
 | 
			
		||||
            {-48230651, -2316852},
 | 
			
		||||
            {-48500850, -1713150},
 | 
			
		||||
            {-48516853, -1676551},
 | 
			
		||||
            {-48974651, -519649},
 | 
			
		||||
            {-49003852, -412551},
 | 
			
		||||
            {-49077850, -129650},
 | 
			
		||||
            {-49239753, 735946},
 | 
			
		||||
            {-49312652, 1188549},
 | 
			
		||||
            {-49349349, 1467647},
 | 
			
		||||
            {-49351650, 1513347},
 | 
			
		||||
            {-49438949, 4165744},
 | 
			
		||||
            {-49433151, 4289947},
 | 
			
		||||
        },
 | 
			
		||||
//        {
 | 
			
		||||
//            {6000, 5851},
 | 
			
		||||
//            {-6000, -5851},
 | 
			
		||||
//            {6000, 5851},
 | 
			
		||||
//        },
 | 
			
		||||
        {
 | 
			
		||||
            {-10836097, -2542396},
 | 
			
		||||
            {-10834396, -1848999},
 | 
			
		||||
            {-10826797, 1172000},
 | 
			
		||||
            {-10825000, 1884403},
 | 
			
		||||
            {-10823299, 2547401},
 | 
			
		||||
            {-10822998, 2642604},
 | 
			
		||||
            {-10807395, 2768299},
 | 
			
		||||
            {-10414299, 3030300},
 | 
			
		||||
            {-9677799, 3516101},
 | 
			
		||||
            {-9555896, 3531002},
 | 
			
		||||
            {-9445198, 3534500},
 | 
			
		||||
            {-9334899, 3534297},
 | 
			
		||||
            {9353000, 3487300},
 | 
			
		||||
            {9463499, 3486904},
 | 
			
		||||
            {9573999, 3482799},
 | 
			
		||||
            {9695901, 3467300},
 | 
			
		||||
            {10684803, 2805603},
 | 
			
		||||
            {10814102, 2717800},
 | 
			
		||||
            {10832803, 2599399},
 | 
			
		||||
            {10836200, 2416797},
 | 
			
		||||
            {10819700, -2650199},
 | 
			
		||||
            {10800401, -2772201},
 | 
			
		||||
            {10670499, -2859397},
 | 
			
		||||
            {9800401, -3436397},
 | 
			
		||||
            {9678201, -3515998},
 | 
			
		||||
            {9556303, -3530998},
 | 
			
		||||
            {9445901, -3534500},
 | 
			
		||||
            {9083999, -3533699},
 | 
			
		||||
            {-9352500, -3487201},
 | 
			
		||||
            {-9462898, -3486797},
 | 
			
		||||
            {-9573501, -3482799},
 | 
			
		||||
            {-9695396, -3467201},
 | 
			
		||||
            {-9816898, -3386997},
 | 
			
		||||
            {-10429500, -2977699},
 | 
			
		||||
            {-10821197, -2713897},
 | 
			
		||||
            {-10836196, -2588001},
 | 
			
		||||
            {-10836097, -2542396},
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            {-47073699, 26300853},
 | 
			
		||||
            {-47009803, 27392650},
 | 
			
		||||
            {-46855804, 28327953},
 | 
			
		||||
            {-46829402, 28427051},
 | 
			
		||||
            {-46764102, 28657550},
 | 
			
		||||
            {-46200401, 30466648},
 | 
			
		||||
            {-46066703, 30832347},
 | 
			
		||||
            {-45887104, 31247554},
 | 
			
		||||
            {-45663700, 31670848},
 | 
			
		||||
            {-45414802, 32080554},
 | 
			
		||||
            {-45273700, 32308956},
 | 
			
		||||
            {-45179702, 32431850},
 | 
			
		||||
            {-45057804, 32549350},
 | 
			
		||||
            {-34670803, 40990154},
 | 
			
		||||
            {-34539802, 41094348},
 | 
			
		||||
            {-34393600, 41184452},
 | 
			
		||||
            {-34284805, 41229953},
 | 
			
		||||
            {-34080402, 41267154},
 | 
			
		||||
            {17335296, 48077648},
 | 
			
		||||
            {18460296, 48153553},
 | 
			
		||||
            {18976600, 48182147},
 | 
			
		||||
            {20403999, 48148555},
 | 
			
		||||
            {20562301, 48131153},
 | 
			
		||||
            {20706001, 48102855},
 | 
			
		||||
            {20938796, 48053150},
 | 
			
		||||
            {21134101, 48010051},
 | 
			
		||||
            {21483192, 47920154},
 | 
			
		||||
            {21904701, 47806346},
 | 
			
		||||
            {22180099, 47670154},
 | 
			
		||||
            {22357795, 47581645},
 | 
			
		||||
            {22615295, 47423046},
 | 
			
		||||
            {22782295, 47294651},
 | 
			
		||||
            {24281791, 45908344},
 | 
			
		||||
            {24405296, 45784854},
 | 
			
		||||
            {41569297, 21952449},
 | 
			
		||||
            {41784301, 21638050},
 | 
			
		||||
            {41938491, 21393650},
 | 
			
		||||
            {42030899, 21245052},
 | 
			
		||||
            {42172996, 21015850},
 | 
			
		||||
            {42415298, 20607151},
 | 
			
		||||
            {42468299, 20504650},
 | 
			
		||||
            {42553100, 20320850},
 | 
			
		||||
            {42584594, 20250644},
 | 
			
		||||
            {42684997, 20004344},
 | 
			
		||||
            {42807098, 19672351},
 | 
			
		||||
            {42939002, 19255153},
 | 
			
		||||
            {43052299, 18693950},
 | 
			
		||||
            {45094100, 7846851},
 | 
			
		||||
            {45118400, 7684154},
 | 
			
		||||
            {47079101, -16562252},
 | 
			
		||||
            {47082000, -16705646},
 | 
			
		||||
            {46916297, -22172447},
 | 
			
		||||
            {46911598, -22294349},
 | 
			
		||||
            {46874893, -22358146},
 | 
			
		||||
            {44866996, -25470146},
 | 
			
		||||
            {30996795, -46852050},
 | 
			
		||||
            {30904998, -46933750},
 | 
			
		||||
            {30864791, -46945850},
 | 
			
		||||
            {9315696, -48169147},
 | 
			
		||||
            {9086494, -48182147},
 | 
			
		||||
            {8895500, -48160049},
 | 
			
		||||
            {8513496, -48099548},
 | 
			
		||||
            {8273696, -48057350},
 | 
			
		||||
            {8180198, -48039051},
 | 
			
		||||
            {7319801, -47854949},
 | 
			
		||||
            {6288299, -47569950},
 | 
			
		||||
            {6238498, -47554248},
 | 
			
		||||
            {5936199, -47453250},
 | 
			
		||||
            {-11930000, -41351551},
 | 
			
		||||
            {-28986402, -33654148},
 | 
			
		||||
            {-29111103, -33597148},
 | 
			
		||||
            {-29201803, -33544147},
 | 
			
		||||
            {-29324401, -33467845},
 | 
			
		||||
            {-29467000, -33352848},
 | 
			
		||||
            {-29606603, -33229351},
 | 
			
		||||
            {-31140401, -31849147},
 | 
			
		||||
            {-31264303, -31736450},
 | 
			
		||||
            {-31385803, -31625452},
 | 
			
		||||
            {-31829103, -31216148},
 | 
			
		||||
            {-32127403, -30935951},
 | 
			
		||||
            {-32253803, -30809648},
 | 
			
		||||
            {-32364803, -30672147},
 | 
			
		||||
            {-34225402, -28078847},
 | 
			
		||||
            {-35819404, -25762451},
 | 
			
		||||
            {-36304801, -25035346},
 | 
			
		||||
            {-36506103, -24696445},
 | 
			
		||||
            {-36574104, -24560146},
 | 
			
		||||
            {-36926700, -23768646},
 | 
			
		||||
            {-39767402, -17341148},
 | 
			
		||||
            {-39904102, -16960147},
 | 
			
		||||
            {-41008602, -11799850},
 | 
			
		||||
            {-43227401, -704147},
 | 
			
		||||
            {-43247303, -577148},
 | 
			
		||||
            {-47057403, 24847454},
 | 
			
		||||
            {-47077602, 25021648},
 | 
			
		||||
            {-47080101, 25128650},
 | 
			
		||||
            {-47082000, 25562953},
 | 
			
		||||
            {-47073699, 26300853},
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::vector<Item> input;
 | 
			
		||||
    input.insert(input.end(), prusaParts().begin(), prusaParts().end());
 | 
			
		||||
//    input.insert(input.end(), prusaParts().begin(), prusaParts().end());
 | 
			
		||||
//    input.insert(input.end(), stegoParts().begin(), stegoParts().end());
 | 
			
		||||
//    input.insert(input.end(), rects.begin(), rects.end());
 | 
			
		||||
    input.insert(input.end(), crasher.begin(), crasher.end());
 | 
			
		||||
 | 
			
		||||
    Box bin(250*SCALE, 210*SCALE);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +450,7 @@ void arrangeRectangles() {
 | 
			
		|||
//    pconf.rotations = {0.0, Pi/2.0, Pi, 3*Pi/2};
 | 
			
		||||
    Packer::SelectionConfig sconf;
 | 
			
		||||
    sconf.allow_parallel = true;
 | 
			
		||||
    sconf.force_parallel = false;
 | 
			
		||||
    sconf.force_parallel = true;
 | 
			
		||||
    sconf.try_reverse_order = false;
 | 
			
		||||
    Packer arrange(bin, min_obj_distance, pconf, sconf);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,8 +467,17 @@ void arrangeRectangles() {
 | 
			
		|||
    Benchmark bench;
 | 
			
		||||
 | 
			
		||||
    bench.start();
 | 
			
		||||
    auto result = arrange.arrange(input.begin(),
 | 
			
		||||
                          input.end());
 | 
			
		||||
    Packer::ResultType result;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        result = arrange.arrange(input.begin(), input.end());
 | 
			
		||||
    } catch(GeometryException& ge) {
 | 
			
		||||
        std::cerr << "Geometry error: " << ge.what() << std::endl;
 | 
			
		||||
        return ;
 | 
			
		||||
    } catch(std::exception& e) {
 | 
			
		||||
        std::cerr << "Exception: " << e.what() << std::endl;
 | 
			
		||||
        return ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bench.stop();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -377,7 +377,8 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) {
 | 
			
		|||
 * them).
 | 
			
		||||
 */
 | 
			
		||||
bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
 | 
			
		||||
             bool first_bin_only)
 | 
			
		||||
             bool first_bin_only,
 | 
			
		||||
             std::function<void(unsigned)> progressind)
 | 
			
		||||
{
 | 
			
		||||
    using ArrangeResult = _IndexedPackGroup<PolygonImpl>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -435,7 +436,7 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
 | 
			
		|||
                biggest = &item;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        shapes.push_back(std::ref(it.second));
 | 
			
		||||
        if(it.second.vertexCount() > 3) shapes.push_back(std::ref(it.second));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    Box bin;
 | 
			
		||||
| 
						 | 
				
			
			@ -471,12 +472,19 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
 | 
			
		|||
    Arranger arranger(bin, min_obj_distance, pcfg, scfg);
 | 
			
		||||
    arranger.useMinimumBoundigBoxRotation();
 | 
			
		||||
 | 
			
		||||
    arranger.progressIndicator(progressind);
 | 
			
		||||
 | 
			
		||||
    std::cout << "Arranging model..." << std::endl;
 | 
			
		||||
    bench.start();
 | 
			
		||||
    // Arrange and return the items with their respective indices within the
 | 
			
		||||
    // input sequence.
 | 
			
		||||
    ArrangeResult result =
 | 
			
		||||
            arranger.arrangeIndexed(shapes.begin(), shapes.end());
 | 
			
		||||
 | 
			
		||||
    ArrangeResult result;
 | 
			
		||||
    try {
 | 
			
		||||
        result = arranger.arrangeIndexed(shapes.begin(), shapes.end());
 | 
			
		||||
    } catch(std::exception& e) {
 | 
			
		||||
        std::cerr << "An exception occured: " << e.what() << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bench.stop();
 | 
			
		||||
    std::cout << "Model arranged in " << bench.getElapsedSec()
 | 
			
		||||
| 
						 | 
				
			
			@ -543,12 +551,13 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
 | 
			
		|||
 | 
			
		||||
/*  arrange objects preserving their instance count
 | 
			
		||||
    but altering their instance positions */
 | 
			
		||||
bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb)
 | 
			
		||||
bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb,
 | 
			
		||||
                            std::function<void(unsigned)> progressind)
 | 
			
		||||
{
 | 
			
		||||
    bool ret = false;
 | 
			
		||||
    if(bb != nullptr && bb->defined) {
 | 
			
		||||
        const bool FIRST_BIN_ONLY = false;
 | 
			
		||||
        ret = arr::arrange(*this, dist, bb, FIRST_BIN_ONLY);
 | 
			
		||||
        ret = arr::arrange(*this, dist, bb, FIRST_BIN_ONLY, progressind);
 | 
			
		||||
    } else {
 | 
			
		||||
        // get the (transformed) size of each instance so that we take
 | 
			
		||||
        // into account their different transformations when packing
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -274,7 +274,8 @@ public:
 | 
			
		|||
    void center_instances_around_point(const Pointf &point);
 | 
			
		||||
    void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
 | 
			
		||||
    TriangleMesh mesh() const;
 | 
			
		||||
    bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL);
 | 
			
		||||
    bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL,
 | 
			
		||||
                         std::function<void(unsigned)> progressind = [](unsigned){});
 | 
			
		||||
    // Croaks if the duplicated objects do not fit the print bed.
 | 
			
		||||
    void duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL);
 | 
			
		||||
    void duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,6 +65,8 @@ REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
 | 
			
		|||
REGISTER_CLASS(TabIface, "GUI::Tab");
 | 
			
		||||
REGISTER_CLASS(PresetUpdater, "PresetUpdater");
 | 
			
		||||
REGISTER_CLASS(OctoPrint, "OctoPrint");
 | 
			
		||||
REGISTER_CLASS(AppController, "AppController");
 | 
			
		||||
REGISTER_CLASS(PrintController, "PrintController");
 | 
			
		||||
 | 
			
		||||
SV* ConfigBase__as_hash(ConfigBase* THIS)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										310
									
								
								xs/src/slic3r/AppController.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								xs/src/slic3r/AppController.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,310 @@
 | 
			
		|||
#include "AppController.hpp"
 | 
			
		||||
 | 
			
		||||
#include <future>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
 | 
			
		||||
#include <slic3r/GUI/GUI.hpp>
 | 
			
		||||
#include <slic3r/GUI/PresetBundle.hpp>
 | 
			
		||||
 | 
			
		||||
#include <PrintConfig.hpp>
 | 
			
		||||
#include <Print.hpp>
 | 
			
		||||
#include <Model.hpp>
 | 
			
		||||
#include <Utils.hpp>
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
class AppControllerBoilerplate::PriMap {
 | 
			
		||||
public:
 | 
			
		||||
    using M = std::unordered_map<std::thread::id, ProgresIndicatorPtr>;
 | 
			
		||||
    std::mutex m;
 | 
			
		||||
    M store;
 | 
			
		||||
    std::thread::id ui_thread;
 | 
			
		||||
 | 
			
		||||
    inline explicit PriMap(std::thread::id uit): ui_thread(uit) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AppControllerBoilerplate::AppControllerBoilerplate()
 | 
			
		||||
    :progressind_(new PriMap(std::this_thread::get_id())) {}
 | 
			
		||||
 | 
			
		||||
AppControllerBoilerplate::~AppControllerBoilerplate() {
 | 
			
		||||
    progressind_.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AppControllerBoilerplate::is_main_thread() const
 | 
			
		||||
{
 | 
			
		||||
    return progressind_->ui_thread == std::this_thread::get_id();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace GUI {
 | 
			
		||||
PresetBundle* get_preset_bundle();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const PrintObjectStep STEP_SLICE                 = posSlice;
 | 
			
		||||
static const PrintObjectStep STEP_PERIMETERS            = posPerimeters;
 | 
			
		||||
static const PrintObjectStep STEP_PREPARE_INFILL        = posPrepareInfill;
 | 
			
		||||
static const PrintObjectStep STEP_INFILL                = posInfill;
 | 
			
		||||
static const PrintObjectStep STEP_SUPPORTMATERIAL       = posSupportMaterial;
 | 
			
		||||
static const PrintStep STEP_SKIRT                       = psSkirt;
 | 
			
		||||
static const PrintStep STEP_BRIM                        = psBrim;
 | 
			
		||||
static const PrintStep STEP_WIPE_TOWER                  = psWipeTower;
 | 
			
		||||
 | 
			
		||||
void AppControllerBoilerplate::progress_indicator(
 | 
			
		||||
        AppControllerBoilerplate::ProgresIndicatorPtr progrind) {
 | 
			
		||||
    progressind_->m.lock();
 | 
			
		||||
    progressind_->store[std::this_thread::get_id()] = progrind;
 | 
			
		||||
    progressind_->m.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppControllerBoilerplate::progress_indicator(unsigned statenum,
 | 
			
		||||
                                                  const std::string &title,
 | 
			
		||||
                                                  const std::string &firstmsg)
 | 
			
		||||
{
 | 
			
		||||
    progressind_->m.lock();
 | 
			
		||||
    progressind_->store[std::this_thread::get_id()] =
 | 
			
		||||
            create_progress_indicator(statenum, title, firstmsg);;
 | 
			
		||||
    progressind_->m.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppControllerBoilerplate::ProgresIndicatorPtr
 | 
			
		||||
AppControllerBoilerplate::progress_indicator() {
 | 
			
		||||
 | 
			
		||||
    PriMap::M::iterator pret;
 | 
			
		||||
    ProgresIndicatorPtr ret;
 | 
			
		||||
 | 
			
		||||
    progressind_->m.lock();
 | 
			
		||||
    if( (pret = progressind_->store.find(std::this_thread::get_id()))
 | 
			
		||||
            == progressind_->store.end())
 | 
			
		||||
    {
 | 
			
		||||
        progressind_->store[std::this_thread::get_id()] = ret =
 | 
			
		||||
                global_progressind_;
 | 
			
		||||
    } else ret = pret->second;
 | 
			
		||||
    progressind_->m.unlock();
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::make_skirt()
 | 
			
		||||
{
 | 
			
		||||
    assert(print_ != nullptr);
 | 
			
		||||
 | 
			
		||||
    // prerequisites
 | 
			
		||||
    for(auto obj : print_->objects) make_perimeters(obj);
 | 
			
		||||
    for(auto obj : print_->objects) infill(obj);
 | 
			
		||||
    for(auto obj : print_->objects) gen_support_material(obj);
 | 
			
		||||
 | 
			
		||||
    if(!print_->state.is_done(STEP_SKIRT)) {
 | 
			
		||||
        print_->state.set_started(STEP_SKIRT);
 | 
			
		||||
        print_->skirt.clear();
 | 
			
		||||
        if(print_->has_skirt()) print_->_make_skirt();
 | 
			
		||||
 | 
			
		||||
        print_->state.set_done(STEP_SKIRT);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::make_brim()
 | 
			
		||||
{
 | 
			
		||||
    assert(print_ != nullptr);
 | 
			
		||||
 | 
			
		||||
    // prerequisites
 | 
			
		||||
    for(auto obj : print_->objects) make_perimeters(obj);
 | 
			
		||||
    for(auto obj : print_->objects) infill(obj);
 | 
			
		||||
    for(auto obj : print_->objects) gen_support_material(obj);
 | 
			
		||||
    make_skirt();
 | 
			
		||||
 | 
			
		||||
    if(!print_->state.is_done(STEP_BRIM)) {
 | 
			
		||||
        print_->state.set_started(STEP_BRIM);
 | 
			
		||||
 | 
			
		||||
        // since this method must be idempotent, we clear brim paths *before*
 | 
			
		||||
        // checking whether we need to generate them
 | 
			
		||||
        print_->brim.clear();
 | 
			
		||||
 | 
			
		||||
        if(print_->config.brim_width > 0) print_->_make_brim();
 | 
			
		||||
 | 
			
		||||
        print_->state.set_done(STEP_BRIM);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::make_wipe_tower()
 | 
			
		||||
{
 | 
			
		||||
    assert(print_ != nullptr);
 | 
			
		||||
 | 
			
		||||
    // prerequisites
 | 
			
		||||
    for(auto obj : print_->objects) make_perimeters(obj);
 | 
			
		||||
    for(auto obj : print_->objects) infill(obj);
 | 
			
		||||
    for(auto obj : print_->objects) gen_support_material(obj);
 | 
			
		||||
    make_skirt();
 | 
			
		||||
    make_brim();
 | 
			
		||||
 | 
			
		||||
    if(!print_->state.is_done(STEP_WIPE_TOWER)) {
 | 
			
		||||
        print_->state.set_started(STEP_WIPE_TOWER);
 | 
			
		||||
 | 
			
		||||
        // since this method must be idempotent, we clear brim paths *before*
 | 
			
		||||
        // checking whether we need to generate them
 | 
			
		||||
        print_->brim.clear();
 | 
			
		||||
 | 
			
		||||
        if(print_->has_wipe_tower()) print_->_make_wipe_tower();
 | 
			
		||||
 | 
			
		||||
        print_->state.set_done(STEP_WIPE_TOWER);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::slice(PrintObject *pobj)
 | 
			
		||||
{
 | 
			
		||||
    assert(pobj != nullptr && print_ != nullptr);
 | 
			
		||||
 | 
			
		||||
    if(pobj->state.is_done(STEP_SLICE)) return;
 | 
			
		||||
 | 
			
		||||
    pobj->state.set_started(STEP_SLICE);
 | 
			
		||||
 | 
			
		||||
    pobj->_slice();
 | 
			
		||||
 | 
			
		||||
    auto msg = pobj->_fix_slicing_errors();
 | 
			
		||||
    if(!msg.empty()) report_issue(IssueType::WARN, msg);
 | 
			
		||||
 | 
			
		||||
    // simplify slices if required
 | 
			
		||||
    if (print_->config.resolution)
 | 
			
		||||
        pobj->_simplify_slices(scale_(print_->config.resolution));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(pobj->layers.empty())
 | 
			
		||||
        report_issue(IssueType::ERR,
 | 
			
		||||
                     "No layers were detected. You might want to repair your "
 | 
			
		||||
                     "STL file(s) or check their size or thickness and retry"
 | 
			
		||||
                     );
 | 
			
		||||
 | 
			
		||||
    pobj->state.set_done(STEP_SLICE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::make_perimeters(PrintObject *pobj)
 | 
			
		||||
{
 | 
			
		||||
    assert(pobj != nullptr);
 | 
			
		||||
 | 
			
		||||
    slice(pobj);
 | 
			
		||||
 | 
			
		||||
    auto&& prgind = progress_indicator();
 | 
			
		||||
 | 
			
		||||
    if (!pobj->state.is_done(STEP_PERIMETERS)) {
 | 
			
		||||
        pobj->_make_perimeters();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::infill(PrintObject *pobj)
 | 
			
		||||
{
 | 
			
		||||
    assert(pobj != nullptr);
 | 
			
		||||
 | 
			
		||||
    make_perimeters(pobj);
 | 
			
		||||
 | 
			
		||||
    if (!pobj->state.is_done(STEP_PREPARE_INFILL)) {
 | 
			
		||||
        pobj->state.set_started(STEP_PREPARE_INFILL);
 | 
			
		||||
 | 
			
		||||
        pobj->_prepare_infill();
 | 
			
		||||
 | 
			
		||||
        pobj->state.set_done(STEP_PREPARE_INFILL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pobj->_infill();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::gen_support_material(PrintObject *pobj)
 | 
			
		||||
{
 | 
			
		||||
    assert(pobj != nullptr);
 | 
			
		||||
 | 
			
		||||
    // prerequisites
 | 
			
		||||
    slice(pobj);
 | 
			
		||||
 | 
			
		||||
    if(!pobj->state.is_done(STEP_SUPPORTMATERIAL)) {
 | 
			
		||||
        pobj->state.set_started(STEP_SUPPORTMATERIAL);
 | 
			
		||||
 | 
			
		||||
        pobj->clear_support_layers();
 | 
			
		||||
 | 
			
		||||
        if((pobj->config.support_material || pobj->config.raft_layers > 0)
 | 
			
		||||
                && pobj->layers.size() > 1) {
 | 
			
		||||
            pobj->_generate_support_material();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pobj->state.set_done(STEP_SUPPORTMATERIAL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::slice()
 | 
			
		||||
{
 | 
			
		||||
    Slic3r::trace(3, "Starting the slicing process.");
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(20u, "Generating perimeters");
 | 
			
		||||
    for(auto obj : print_->objects) make_perimeters(obj);
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(60u, "Infilling layers");
 | 
			
		||||
    for(auto obj : print_->objects) infill(obj);
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(70u, "Generating support material");
 | 
			
		||||
    for(auto obj : print_->objects) gen_support_material(obj);
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->message_fmt("Weight: %.1fg, Cost: %.1f",
 | 
			
		||||
                                    print_->total_weight,
 | 
			
		||||
                                    print_->total_cost);
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->state(85u);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(88u, "Generating skirt");
 | 
			
		||||
    make_skirt();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(90u, "Generating brim");
 | 
			
		||||
    make_brim();
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(95u, "Generating wipe tower");
 | 
			
		||||
    make_wipe_tower();
 | 
			
		||||
 | 
			
		||||
    progress_indicator()->update(100u, "Done");
 | 
			
		||||
 | 
			
		||||
    // time to make some statistics..
 | 
			
		||||
 | 
			
		||||
    Slic3r::trace(3, "Slicing process finished.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IProgressIndicator::message_fmt(
 | 
			
		||||
        const std::string &fmtstr, ...) {
 | 
			
		||||
    std::stringstream ss;
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, fmtstr);
 | 
			
		||||
 | 
			
		||||
    auto fmt = fmtstr.begin();
 | 
			
		||||
 | 
			
		||||
    while (*fmt != '\0') {
 | 
			
		||||
        if (*fmt == 'd') {
 | 
			
		||||
            int i = va_arg(args, int);
 | 
			
		||||
            ss << i << '\n';
 | 
			
		||||
        } else if (*fmt == 'c') {
 | 
			
		||||
            // note automatic conversion to integral type
 | 
			
		||||
            int c = va_arg(args, int);
 | 
			
		||||
            ss << static_cast<char>(c) << '\n';
 | 
			
		||||
        } else if (*fmt == 'f') {
 | 
			
		||||
            double d = va_arg(args, double);
 | 
			
		||||
            ss << d << '\n';
 | 
			
		||||
        }
 | 
			
		||||
        ++fmt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    va_end(args);
 | 
			
		||||
    message(ss.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppController::arrange_model()
 | 
			
		||||
{
 | 
			
		||||
    std::async(supports_asynch()? std::launch::async : std::launch::deferred,
 | 
			
		||||
               [this](){
 | 
			
		||||
        auto pind = progress_indicator();
 | 
			
		||||
 | 
			
		||||
    // my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($self->{config}->bed_shape);
 | 
			
		||||
    // my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb);
 | 
			
		||||
        double dist = GUI::get_preset_bundle()->full_config().option("min_object_distance")->getFloat();
 | 
			
		||||
 | 
			
		||||
        std::cout << dist << std::endl;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										267
									
								
								xs/src/slic3r/AppController.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								xs/src/slic3r/AppController.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,267 @@
 | 
			
		|||
#ifndef APPCONTROLLER_HPP
 | 
			
		||||
#define APPCONTROLLER_HPP
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include "IProgressIndicator.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
class Model;
 | 
			
		||||
class Print;
 | 
			
		||||
class PrintObject;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief A boilerplate class for creating application logic. It should provide
 | 
			
		||||
 * features as issue reporting and progress indication, etc...
 | 
			
		||||
 *
 | 
			
		||||
 * The lower lever UI independent classes can be manipulated with a subclass
 | 
			
		||||
 * of this controller class. We can also catch any exceptions that lower level
 | 
			
		||||
 * methods could throw and display appropriate errors and warnings.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that the outer and the inner interface of this class is free from any
 | 
			
		||||
 * UI toolkit dependencies. We can implement it with any UI framework or make it
 | 
			
		||||
 * a cli client.
 | 
			
		||||
 */
 | 
			
		||||
class AppControllerBoilerplate {
 | 
			
		||||
    class PriMap;   // Some structure to store progress indication data
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /// A Progress indicator object smart pointer
 | 
			
		||||
    using ProgresIndicatorPtr = std::shared_ptr<IProgressIndicator>;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Pimpl data for thread safe progress indication features
 | 
			
		||||
    std::unique_ptr<PriMap> progressind_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    AppControllerBoilerplate();
 | 
			
		||||
    ~AppControllerBoilerplate();
 | 
			
		||||
 | 
			
		||||
    using Path = std::string;
 | 
			
		||||
    using PathList = std::vector<Path>;
 | 
			
		||||
 | 
			
		||||
    /// Common runtime issue types
 | 
			
		||||
    enum class IssueType {
 | 
			
		||||
        INFO,
 | 
			
		||||
        WARN,
 | 
			
		||||
        WARN_Q,     // Warning with a question to continue
 | 
			
		||||
        ERR,
 | 
			
		||||
        FATAL
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Query some paths from the user.
 | 
			
		||||
     *
 | 
			
		||||
     * It should display a file chooser dialog in case of a UI application.
 | 
			
		||||
     * @param title Title of a possible query dialog.
 | 
			
		||||
     * @param extensions Recognized file extensions.
 | 
			
		||||
     * @return Returns a list of paths choosed by the user.
 | 
			
		||||
     */
 | 
			
		||||
    PathList query_destination_paths(
 | 
			
		||||
            const std::string& title,
 | 
			
		||||
            const std::string& extensions) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Same as query_destination_paths but works for directories only.
 | 
			
		||||
     */
 | 
			
		||||
    PathList query_destination_dirs(
 | 
			
		||||
            const std::string& title) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Same as query_destination_paths but returns only one path.
 | 
			
		||||
     */
 | 
			
		||||
    Path query_destination_path(
 | 
			
		||||
            const std::string& title,
 | 
			
		||||
            const std::string& extensions,
 | 
			
		||||
            const std::string& hint = "") const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Report an issue to the user be it fatal or recoverable.
 | 
			
		||||
     *
 | 
			
		||||
     * In a UI app this should display some message dialog.
 | 
			
		||||
     *
 | 
			
		||||
     * @param issuetype The type of the runtime issue.
 | 
			
		||||
     * @param description A somewhat longer description of the issue.
 | 
			
		||||
     * @param brief A very brief description. Can be used for message dialog
 | 
			
		||||
     * title.
 | 
			
		||||
     */
 | 
			
		||||
    bool report_issue(IssueType issuetype,
 | 
			
		||||
                      const std::string& description,
 | 
			
		||||
                      const std::string& brief = "");
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Set up a progress indicator for the current thread.
 | 
			
		||||
     * @param progrind An already created progress indicator object.
 | 
			
		||||
     */
 | 
			
		||||
    void progress_indicator(ProgresIndicatorPtr progrind);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Create and set up a new progress indicator for the current thread.
 | 
			
		||||
     * @param statenum The number of states for the given procedure.
 | 
			
		||||
     * @param title The title of the procedure.
 | 
			
		||||
     * @param firstmsg The message for the first subtask to be displayed.
 | 
			
		||||
     */
 | 
			
		||||
    void progress_indicator(unsigned statenum,
 | 
			
		||||
                            const std::string& title,
 | 
			
		||||
                            const std::string& firstmsg = "");
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Return the progress indicator set up for the current thread. This
 | 
			
		||||
     * can be empty as well.
 | 
			
		||||
     * @return A progress indicator object implementing IProgressIndicator. If
 | 
			
		||||
     * a global progress indicator is available for the current implementation
 | 
			
		||||
     * than this will be set up for the current thread and returned.
 | 
			
		||||
     */
 | 
			
		||||
    ProgresIndicatorPtr progress_indicator();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief A predicate telling the caller whether it is the thread that
 | 
			
		||||
     * created the AppConroller object itself. This probably means that the
 | 
			
		||||
     * execution is in the UI thread. Otherwise it returns false meaning that
 | 
			
		||||
     * some worker thread called this function.
 | 
			
		||||
     * @return Return true for the same caller thread that created this
 | 
			
		||||
     * object and false for every other.
 | 
			
		||||
     */
 | 
			
		||||
    bool is_main_thread() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief The frontend supports asynch execution.
 | 
			
		||||
     *
 | 
			
		||||
     * A Graphic UI will support this, a CLI may not. This can be used in
 | 
			
		||||
     * subclass methods to decide whether to start threads for block free UI.
 | 
			
		||||
     *
 | 
			
		||||
     * Note that even a progress indicator's update called regularly can solve
 | 
			
		||||
     * the blocking UI problem in some cases even when an event loop is present.
 | 
			
		||||
     * This is how wxWidgets gauge work but creating a separate thread will make
 | 
			
		||||
     * the UI even more fluent.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if a job or method can be executed asynchronously, false
 | 
			
		||||
     * otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    bool supports_asynch() const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Create a new progress indicator and return a smart pointer to it.
 | 
			
		||||
     * @param statenum The number of states for the given procedure.
 | 
			
		||||
     * @param title The title of the procedure.
 | 
			
		||||
     * @param firstmsg The message for the first subtask to be displayed.
 | 
			
		||||
     * @return Smart pointer to the created object.
 | 
			
		||||
     */
 | 
			
		||||
    ProgresIndicatorPtr create_progress_indicator(
 | 
			
		||||
            unsigned statenum,
 | 
			
		||||
            const std::string& title,
 | 
			
		||||
            const std::string& firstmsg = "") const;
 | 
			
		||||
 | 
			
		||||
    // This is a global progress indicator placeholder. In the Slic3r UI it can
 | 
			
		||||
    // contain the progress indicator on the statusbar.
 | 
			
		||||
    ProgresIndicatorPtr global_progressind_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Implementation of the printing logic.
 | 
			
		||||
 */
 | 
			
		||||
class PrintController: public AppControllerBoilerplate {
 | 
			
		||||
    Print *print_ = nullptr;
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    void make_skirt();
 | 
			
		||||
    void make_brim();
 | 
			
		||||
    void make_wipe_tower();
 | 
			
		||||
 | 
			
		||||
    void make_perimeters(PrintObject *pobj);
 | 
			
		||||
    void infill(PrintObject *pobj);
 | 
			
		||||
    void gen_support_material(PrintObject *pobj);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // Must be public for perl to use it
 | 
			
		||||
    explicit inline PrintController(Print *print): print_(print) {}
 | 
			
		||||
 | 
			
		||||
    PrintController(const PrintController&) = delete;
 | 
			
		||||
    PrintController(PrintController&&) = delete;
 | 
			
		||||
 | 
			
		||||
    using Ptr = std::unique_ptr<PrintController>;
 | 
			
		||||
 | 
			
		||||
    inline static Ptr create(Print *print) {
 | 
			
		||||
        return PrintController::Ptr( new PrintController(print) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Slice one pront object.
 | 
			
		||||
     * @param pobj The print object.
 | 
			
		||||
     */
 | 
			
		||||
    void slice(PrintObject *pobj);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Slice the loaded print scene.
 | 
			
		||||
     */
 | 
			
		||||
    void slice();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Top level controller.
 | 
			
		||||
 */
 | 
			
		||||
class AppController: public AppControllerBoilerplate {
 | 
			
		||||
    Model *model_ = nullptr;
 | 
			
		||||
    PrintController::Ptr printctl;
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get the print controller object.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Return a raw pointer instead of a smart one for perl to be able
 | 
			
		||||
     * to use this function and access the print controller.
 | 
			
		||||
     */
 | 
			
		||||
    PrintController * print_ctl() { return printctl.get(); }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Set a model object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param model A raw pointer to the model object. This can be used from
 | 
			
		||||
     * perl.
 | 
			
		||||
     */
 | 
			
		||||
    void set_model(Model *model) { model_ = model; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Set the print object from perl.
 | 
			
		||||
     *
 | 
			
		||||
     * This will create a print controller that will then be accessible from
 | 
			
		||||
     * perl.
 | 
			
		||||
     * @param print A print object which can be a perl-ish extension as well.
 | 
			
		||||
     */
 | 
			
		||||
    void set_print(Print *print) {
 | 
			
		||||
        printctl = PrintController::create(print);
 | 
			
		||||
        printctl->progress_indicator(progress_indicator());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Set up a global progress indicator.
 | 
			
		||||
     *
 | 
			
		||||
     * In perl we have a progress indicating status bar on the bottom of the
 | 
			
		||||
     * window which is defined and created in perl. We can pass the ID-s of the
 | 
			
		||||
     * gauge and the statusbar id and make a wrapper implementation of the
 | 
			
		||||
     * IProgressIndicator interface so we can use this GUI widget from C++.
 | 
			
		||||
     *
 | 
			
		||||
     * This function should be called from perl.
 | 
			
		||||
     *
 | 
			
		||||
     * @param gauge_id The ID of the gague widget of the status bar.
 | 
			
		||||
     * @param statusbar_id The ID of the status bar.
 | 
			
		||||
     */
 | 
			
		||||
    void set_global_progress_indicator(unsigned gauge_id,
 | 
			
		||||
                                          unsigned statusbar_id);
 | 
			
		||||
 | 
			
		||||
    void arrange_model();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // APPCONTROLLER_HPP
 | 
			
		||||
							
								
								
									
										295
									
								
								xs/src/slic3r/AppControllerWx.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								xs/src/slic3r/AppControllerWx.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,295 @@
 | 
			
		|||
#include "AppController.hpp"
 | 
			
		||||
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include <future>
 | 
			
		||||
 | 
			
		||||
#include <slic3r/GUI/GUI.hpp>
 | 
			
		||||
 | 
			
		||||
#include <wx/app.h>
 | 
			
		||||
#include <wx/filedlg.h>
 | 
			
		||||
#include <wx/msgdlg.h>
 | 
			
		||||
#include <wx/progdlg.h>
 | 
			
		||||
#include <wx/gauge.h>
 | 
			
		||||
#include <wx/statusbr.h>
 | 
			
		||||
#include <wx/event.h>
 | 
			
		||||
 | 
			
		||||
// This source file implements the UI dependent methods of the AppControllers.
 | 
			
		||||
// It will be clear what is needed to be reimplemented in case of a UI framework
 | 
			
		||||
// change or a CLI client creation. In this particular case we use wxWidgets to
 | 
			
		||||
// implement everything.
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
bool AppControllerBoilerplate::supports_asynch() const
 | 
			
		||||
{
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppControllerBoilerplate::PathList
 | 
			
		||||
AppControllerBoilerplate::query_destination_paths(
 | 
			
		||||
        const std::string &title,
 | 
			
		||||
        const std::string &extensions) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    wxFileDialog dlg(wxTheApp->GetTopWindow(), wxString(title) );
 | 
			
		||||
    dlg.SetWildcard(extensions);
 | 
			
		||||
 | 
			
		||||
    dlg.ShowModal();
 | 
			
		||||
 | 
			
		||||
    wxArrayString paths;
 | 
			
		||||
    dlg.GetPaths(paths);
 | 
			
		||||
 | 
			
		||||
    PathList ret(paths.size(), "");
 | 
			
		||||
    for(auto& p : paths) ret.push_back(p.ToStdString());
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppControllerBoilerplate::Path
 | 
			
		||||
AppControllerBoilerplate::query_destination_path(
 | 
			
		||||
        const std::string &title,
 | 
			
		||||
        const std::string &extensions,
 | 
			
		||||
        const std::string& hint) const
 | 
			
		||||
{
 | 
			
		||||
    wxFileDialog dlg(wxTheApp->GetTopWindow(), title );
 | 
			
		||||
    dlg.SetWildcard(extensions);
 | 
			
		||||
 | 
			
		||||
    dlg.SetFilename(hint);
 | 
			
		||||
 | 
			
		||||
    Path ret;
 | 
			
		||||
 | 
			
		||||
    if(dlg.ShowModal() == wxID_OK) {
 | 
			
		||||
        ret = Path(dlg.GetPath());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AppControllerBoilerplate::report_issue(IssueType issuetype,
 | 
			
		||||
                                 const std::string &description,
 | 
			
		||||
                                 const std::string &brief)
 | 
			
		||||
{
 | 
			
		||||
    auto icon = wxICON_INFORMATION;
 | 
			
		||||
    auto style = wxOK|wxCENTRE;
 | 
			
		||||
    switch(issuetype) {
 | 
			
		||||
    case IssueType::INFO:   break;
 | 
			
		||||
    case IssueType::WARN:   icon = wxICON_WARNING; break;
 | 
			
		||||
    case IssueType::WARN_Q: icon = wxICON_WARNING; style |= wxCANCEL; break;
 | 
			
		||||
    case IssueType::ERR:
 | 
			
		||||
    case IssueType::FATAL:  icon = wxICON_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto ret = wxMessageBox(description, brief, icon | style);
 | 
			
		||||
    return ret != wxCANCEL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
wxDEFINE_EVENT(PROGRESS_STATUS_UPDATE_EVENT, wxCommandEvent);
 | 
			
		||||
 | 
			
		||||
namespace  {
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A simple thread safe progress dialog implementation that can be used from
 | 
			
		||||
 * the main thread as well.
 | 
			
		||||
 */
 | 
			
		||||
class GuiProgressIndicator:
 | 
			
		||||
        public IProgressIndicator, public wxEvtHandler {
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<wxProgressDialog> gauge_;
 | 
			
		||||
    using Base = IProgressIndicator;
 | 
			
		||||
    wxString message_;
 | 
			
		||||
    int range_; wxString title_;
 | 
			
		||||
    unsigned prc_ = 0;
 | 
			
		||||
    bool is_asynch_ = false;
 | 
			
		||||
 | 
			
		||||
    const int id_ = wxWindow::NewControlId();
 | 
			
		||||
 | 
			
		||||
    // status update handler
 | 
			
		||||
    void _state( wxCommandEvent& evt) {
 | 
			
		||||
        unsigned st = evt.GetInt();
 | 
			
		||||
        _state(st);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Status update implementation
 | 
			
		||||
    void _state( unsigned st) {
 | 
			
		||||
        if(st < max()) {
 | 
			
		||||
            if(!gauge_) gauge_ = std::make_shared<wxProgressDialog>(
 | 
			
		||||
                    title_, message_, range_, wxTheApp->GetTopWindow(),
 | 
			
		||||
                        wxPD_APP_MODAL | wxPD_AUTO_HIDE
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if(!gauge_->IsShown()) gauge_->ShowModal();
 | 
			
		||||
            Base::state(st);
 | 
			
		||||
            gauge_->Update(static_cast<int>(st), message_);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(st == max()) {
 | 
			
		||||
            prc_++;
 | 
			
		||||
            if(prc_ == Base::procedure_count())  {
 | 
			
		||||
                gauge_.reset();
 | 
			
		||||
                prc_ = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /// Setting whether it will be used from the UI thread or some worker thread
 | 
			
		||||
    inline void asynch(bool is) { is_asynch_ = is; }
 | 
			
		||||
 | 
			
		||||
    /// Get the mode of parallel operation.
 | 
			
		||||
    inline bool asynch() const { return is_asynch_; }
 | 
			
		||||
 | 
			
		||||
    inline GuiProgressIndicator(int range, const std::string& title,
 | 
			
		||||
                                const std::string& firstmsg) :
 | 
			
		||||
        range_(range), message_(_(firstmsg)), title_(_(title))
 | 
			
		||||
    {
 | 
			
		||||
        Base::max(static_cast<float>(range));
 | 
			
		||||
        Base::states(static_cast<unsigned>(range));
 | 
			
		||||
 | 
			
		||||
        Bind(PROGRESS_STATUS_UPDATE_EVENT,
 | 
			
		||||
             &GuiProgressIndicator::_state,
 | 
			
		||||
             this, id_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void cancel() override {
 | 
			
		||||
        update(max(), "Abort");
 | 
			
		||||
        IProgressIndicator::cancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void state(float val) override {
 | 
			
		||||
        if( val >= 1.0) state(static_cast<unsigned>(val));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void state(unsigned st) {
 | 
			
		||||
        // send status update event
 | 
			
		||||
        if(is_asynch_) {
 | 
			
		||||
            auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
 | 
			
		||||
            evt->SetInt(st);
 | 
			
		||||
            wxQueueEvent(this, evt);
 | 
			
		||||
        } else _state(st);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void message(const std::string & msg) override {
 | 
			
		||||
        message_ = _(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void messageFmt(const std::string& fmt, ...) {
 | 
			
		||||
        va_list arglist;
 | 
			
		||||
        va_start(arglist, fmt);
 | 
			
		||||
        message_ = wxString::Format(_(fmt), arglist);
 | 
			
		||||
        va_end(arglist);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void title(const std::string & title) override {
 | 
			
		||||
        title_ = _(title);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppControllerBoilerplate::ProgresIndicatorPtr
 | 
			
		||||
AppControllerBoilerplate::create_progress_indicator(
 | 
			
		||||
        unsigned statenum, const std::string& title,
 | 
			
		||||
        const std::string& firstmsg) const
 | 
			
		||||
{
 | 
			
		||||
    auto pri =
 | 
			
		||||
            std::make_shared<GuiProgressIndicator>(statenum, title, firstmsg);
 | 
			
		||||
 | 
			
		||||
    // We set up the mode of operation depending of the creator thread's
 | 
			
		||||
    // identity
 | 
			
		||||
    pri->asynch(!is_main_thread());
 | 
			
		||||
 | 
			
		||||
    return pri;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
// A wrapper progress indicator class around the statusbar created in perl.
 | 
			
		||||
class Wrapper: public IProgressIndicator, public wxEvtHandler {
 | 
			
		||||
    wxGauge *gauge_;
 | 
			
		||||
    wxStatusBar *stbar_;
 | 
			
		||||
    using Base = IProgressIndicator;
 | 
			
		||||
    std::string message_;
 | 
			
		||||
    AppControllerBoilerplate& ctl_;
 | 
			
		||||
 | 
			
		||||
    void showProgress(bool show = true) {
 | 
			
		||||
        gauge_->Show(show);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void _state(unsigned st) {
 | 
			
		||||
        if( st <= max() ) {
 | 
			
		||||
            Base::state(st);
 | 
			
		||||
 | 
			
		||||
            if(!gauge_->IsShown()) showProgress(true);
 | 
			
		||||
 | 
			
		||||
            stbar_->SetStatusText(message_);
 | 
			
		||||
            if(st == gauge_->GetRange()) {
 | 
			
		||||
                gauge_->SetValue(0);
 | 
			
		||||
                showProgress(false);
 | 
			
		||||
            } else {
 | 
			
		||||
                gauge_->SetValue(static_cast<int>(st));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // status update handler
 | 
			
		||||
    void _state( wxCommandEvent& evt) {
 | 
			
		||||
        unsigned st = evt.GetInt(); _state(st);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const int id_ = wxWindow::NewControlId();
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    inline Wrapper(wxGauge *gauge, wxStatusBar *stbar,
 | 
			
		||||
                   AppControllerBoilerplate& ctl):
 | 
			
		||||
        gauge_(gauge), stbar_(stbar), ctl_(ctl)
 | 
			
		||||
    {
 | 
			
		||||
        Base::max(static_cast<float>(gauge->GetRange()));
 | 
			
		||||
        Base::states(static_cast<unsigned>(gauge->GetRange()));
 | 
			
		||||
 | 
			
		||||
        Bind(PROGRESS_STATUS_UPDATE_EVENT,
 | 
			
		||||
             &Wrapper::_state,
 | 
			
		||||
             this, id_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void state(float val) override {
 | 
			
		||||
        if(val >= 1.0) state(unsigned(val));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void state(unsigned st) {
 | 
			
		||||
        if(!ctl_.is_main_thread()) {
 | 
			
		||||
            auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
 | 
			
		||||
            evt->SetInt(st);
 | 
			
		||||
            wxQueueEvent(this, evt);
 | 
			
		||||
        } else _state(st);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void message(const std::string & msg) override {
 | 
			
		||||
        message_ = msg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void message_fmt(const std::string& fmt, ...) override {
 | 
			
		||||
        va_list arglist;
 | 
			
		||||
        va_start(arglist, fmt);
 | 
			
		||||
        message_ = wxString::Format(_(fmt), arglist);
 | 
			
		||||
        va_end(arglist);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void title(const std::string & /*title*/) override {}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppController::set_global_progress_indicator(
 | 
			
		||||
        unsigned gid,
 | 
			
		||||
        unsigned sid)
 | 
			
		||||
{
 | 
			
		||||
    wxGauge* gauge = dynamic_cast<wxGauge*>(wxWindow::FindWindowById(gid));
 | 
			
		||||
    wxStatusBar* sb = dynamic_cast<wxStatusBar*>(wxWindow::FindWindowById(sid));
 | 
			
		||||
 | 
			
		||||
    if(gauge && sb) {
 | 
			
		||||
        global_progressind_ = std::make_shared<Wrapper>(gauge, sb, *this);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								xs/src/slic3r/IProgressIndicator.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								xs/src/slic3r/IProgressIndicator.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
#ifndef IPROGRESSINDICATOR_HPP
 | 
			
		||||
#define IPROGRESSINDICATOR_HPP
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Generic progress indication interface.
 | 
			
		||||
 */
 | 
			
		||||
class IProgressIndicator {
 | 
			
		||||
public:
 | 
			
		||||
    using CancelFn = std::function<void(void)>; // Cancel functio signature.
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    float state_ = .0f, max_ = 1.f, step_;
 | 
			
		||||
    CancelFn cancelfunc_ = [](){};
 | 
			
		||||
    unsigned proc_count_ = 1;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    inline virtual ~IProgressIndicator() {}
 | 
			
		||||
 | 
			
		||||
    /// Get the maximum of the progress range.
 | 
			
		||||
    float max() const { return max_; }
 | 
			
		||||
 | 
			
		||||
    /// Get the current progress state
 | 
			
		||||
    float state() const { return state_; }
 | 
			
		||||
 | 
			
		||||
    /// Set the maximum of hte progress range
 | 
			
		||||
    virtual void max(float maxval) { max_ = maxval; }
 | 
			
		||||
 | 
			
		||||
    /// Set the current state of the progress.
 | 
			
		||||
    virtual void state(float val)  { state_ = val; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Number of states int the progress. Can be used insted of giving a
 | 
			
		||||
     * maximum value.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void states(unsigned statenum) {
 | 
			
		||||
        step_ = max_ / statenum;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Message shown on the next status update.
 | 
			
		||||
    virtual void message(const std::string&) = 0;
 | 
			
		||||
 | 
			
		||||
    /// Title of the operaton.
 | 
			
		||||
    virtual void title(const std::string&) = 0;
 | 
			
		||||
 | 
			
		||||
    /// Formatted message for the next status update. Works just like sprinf.
 | 
			
		||||
    virtual void message_fmt(const std::string& fmt, ...);
 | 
			
		||||
 | 
			
		||||
    /// Set up a cancel callback for the operation if feasible.
 | 
			
		||||
    inline void on_cancel(CancelFn func) { cancelfunc_ = func; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Explicitly shut down the progress indicator and call the associated
 | 
			
		||||
     * callback.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void cancel() { cancelfunc_(); }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * \brief Set up how many subprocedures does the whole operation contain.
 | 
			
		||||
     *
 | 
			
		||||
     * This was neccesary from practical reasons. If the progress indicator is
 | 
			
		||||
     * a dialog and we want to show the progress of a few sub operations than
 | 
			
		||||
     * the dialog wont be closed and reopened each time a new sub operation is
 | 
			
		||||
     * started. This is not a mandatory feature and can be ignored completely.
 | 
			
		||||
     */
 | 
			
		||||
    inline void procedure_count(unsigned pc) { proc_count_ = pc; }
 | 
			
		||||
 | 
			
		||||
    /// Get the current procedure count
 | 
			
		||||
    inline unsigned procedure_count() const { return proc_count_; }
 | 
			
		||||
 | 
			
		||||
    /// Convinience function to call message and status update in one function.
 | 
			
		||||
    void update(float st, const std::string& msg) {
 | 
			
		||||
        message(msg); state(st);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // IPROGRESSINDICATOR_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +80,7 @@ extern "C" {
 | 
			
		|||
#include <Polygon.hpp>
 | 
			
		||||
#include <Polyline.hpp>
 | 
			
		||||
#include <TriangleMesh.hpp>
 | 
			
		||||
#include <slic3r/AppController.hpp>
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								xs/xsp/AppController.xsp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								xs/xsp/AppController.xsp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
%module{Slic3r::XS};
 | 
			
		||||
 | 
			
		||||
%{
 | 
			
		||||
#include <xsinit.h>
 | 
			
		||||
#include "slic3r/AppController.hpp"
 | 
			
		||||
#include "libslic3r/Model.hpp"
 | 
			
		||||
#include "libslic3r/Print.hpp"
 | 
			
		||||
%}
 | 
			
		||||
 | 
			
		||||
%name{Slic3r::PrintController} class PrintController {
 | 
			
		||||
 | 
			
		||||
    PrintController(Print *print);
 | 
			
		||||
 | 
			
		||||
    void slice();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
%name{Slic3r::AppController} class AppController {
 | 
			
		||||
 | 
			
		||||
    AppController();
 | 
			
		||||
 | 
			
		||||
    PrintController *print_ctl();
 | 
			
		||||
    void set_model(Model *model);
 | 
			
		||||
    void set_print(Print *print);
 | 
			
		||||
    void set_global_progress_indicator(unsigned gauge_id, unsigned statusbar_id);
 | 
			
		||||
 | 
			
		||||
    void arrange_model();
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -216,6 +216,8 @@ Ref<PrintObjectSupportMaterial>   O_OBJECT_SLIC3R_T
 | 
			
		|||
Clone<PrintObjectSupportMaterial> O_OBJECT_SLIC3R_T
 | 
			
		||||
 | 
			
		||||
AppConfig*	                O_OBJECT_SLIC3R
 | 
			
		||||
AppController*              O_OBJECT_SLIC3R
 | 
			
		||||
PrintController*            O_OBJECT_SLIC3R
 | 
			
		||||
Ref<AppConfig>         		O_OBJECT_SLIC3R_T
 | 
			
		||||
 | 
			
		||||
GLShader*                  	O_OBJECT_SLIC3R
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,3 +268,5 @@
 | 
			
		|||
    $CVar = (PrintObjectStep)SvUV($PerlVar);
 | 
			
		||||
  %};
 | 
			
		||||
};
 | 
			
		||||
%typemap{AppController*};
 | 
			
		||||
%typemap{PrintController*};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue