void ProcessController::ConvertToGCode(string &GcodeTxt, const string &GcodeStart, const string &GcodeLayer, const string &GcodeEnd) { if(gui) {gui->ProgressBar->value(0); gui->ProgressBar->label("Converting"); gui->ProgressBar->maximum(Max.z); } // Make Layers uint LayerNr = 0; printOffset = PrintMargin; float z=Min.z+LayerThickness*0.5f; // Offset it a bit in Z, z=0 gives a empty slice because no triangles crosses this Z value gcode.commands.clear(); float destinationZ=PrintMargin.z; if(RaftEnable) { printOffset += Vector3f(RaftSize, RaftSize, 0); MakeRaft(destinationZ); } float E=0.0f; while(z<Max.z+LayerThickness*0.5f) { if(gui) { gui->ProgressBar->value(z); gui->ProgressBar->redraw(); Fl::check(); } for(uint o=0;o<rfo.Objects.size();o++) for(uint f=0;f<rfo.Objects[o].files.size();f++) { STL* stl = &rfo.Objects[o].files[f].stl; // Get a pointer to the object Matrix4f T = GetSTLTransformationMatrix(o,f); Vector3f t = T.getTranslation(); t+= Vector3f(PrintMargin.x+RaftSize*RaftEnable, PrintMargin.y+RaftSize*RaftEnable, 0); T.setTranslation(t); CuttingPlane plane; stl->CalcCuttingPlane(z, plane, T); // output is alot of un-connected line segments with individual vertices, describing the outline float hackedZ = z; while(plane.LinkSegments(hackedZ, ExtrudedMaterialWidth*0.5f, DisplayCuttingPlane, m_ShrinkQuality, ShellCount) == false) // If segment linking fails, re-calc a new layer close to this one, and use that. { // This happens when there's triangles missing in the input STL hackedZ+= 0.1f; plane.polygons.clear(); stl->CalcCuttingPlane(hackedZ, plane, T); // output is alot of un-connected line segments with individual vertices, describing the outline } // inFill vector<Vector2f> infill; CuttingPlane infillCuttingPlane = plane; infillCuttingPlane.polygons = infillCuttingPlane.offsetPolygons; infillCuttingPlane.vertices = infillCuttingPlane.offsetVertices; infillCuttingPlane.offsetPolygons.clear(); infillCuttingPlane.offsetVertices.clear(); if(ShellOnly == false) { if(m_ShrinkQuality == SHRINK_FAST) infillCuttingPlane.ShrinkFast(ExtrudedMaterialWidth*0.5f, z, DisplayCuttingPlane, false, ShellCount); else infillCuttingPlane.ShrinkNice(ExtrudedMaterialWidth*0.5f, z, DisplayCuttingPlane, false, ShellCount); infillCuttingPlane.CalcInFill(infill, LayerNr, destinationZ, InfillDistance, InfillRotation, InfillRotationPrLayer, DisplayDebuginFill); } // Make the GCode from the plane and the infill plane.MakeGcode(infill, gcode, E, destinationZ, MinPrintSpeedXY, MaxPrintSpeedXY, MinPrintSpeedZ, MaxPrintSpeedZ, DistanceToReachFullSpeed, extrusionFactor, UseIncrementalEcode, Use3DGcode, EnableAcceleration); } LayerNr++; destinationZ += LayerThickness; z+=LayerThickness; } GcodeTxt.clear(); gcode.MakeText(GcodeTxt, GcodeStart, GcodeLayer, GcodeEnd, UseIncrementalEcode, Use3DGcode); gui->ProgressBar->label("Done"); }
void Model::ConvertToGCode() { if (is_calculating) { return; } is_calculating=true; // default: settings.SelectExtruder(0); Glib::TimeVal start_time; start_time.assign_current_time(); gcode.clear(); GCodeState state(gcode); Infill::clearPatterns(); Vector3d printOffset = settings.getPrintMargin(); double printOffsetZ = printOffset.z(); // Make Layers lastlayer = NULL; Slice(); //CleanupLayers(); MakeShells(); if (settings.get_boolean("Slicing","DoInfill") && !settings.get_boolean("Slicing","NoTopAndBottom") && (settings.get_double("Slicing","SolidThickness") > 0 || settings.get_integer("Slicing","ShellCount") > 0)) // not bridging when support MakeUncoveredPolygons( settings.get_boolean("Slicing","MakeDecor"), !settings.get_boolean("Slicing","NoBridges") && !settings.get_boolean("Slicing","Support") ); if (settings.get_boolean("Slicing","Support")) // easier before having multiplied uncovered bottoms MakeSupportPolygons(settings.get_double("Slicing","SupportWiden")); MakeFullSkins(); // must before multiplied uncovered bottoms MultiplyUncoveredPolygons(); if (settings.get_boolean("Slicing","Skirt")) MakeSkirt(); CalcInfill(); if (settings.get_boolean("Raft","Enable")) { printOffset += Vector3d (settings.get_double("Raft","Size"), 0); MakeRaft (state, printOffsetZ); // printOffsetZ will have height of raft added } state.ResetLastWhere(Vector3d(0,0,0)); uint count = layers.size(); m_progress->start (_("Making Lines"), count+1); state.AppendCommand(MILLIMETERSASUNITS, false, _("Millimeters")); state.AppendCommand(ABSOLUTEPOSITIONING, false, _("Absolute Pos")); if (settings.get_boolean("Slicing","RelativeEcode")) state.AppendCommand(RELATIVE_ECODE, false, _("Relative E Code")); else state.AppendCommand(ABSOLUTE_ECODE, false, _("Absolute E Code")); bool cont = true; vector<PLine3> plines; bool farthestStart = settings.get_boolean("Slicing","FarthestLayerStart"); Vector3d start = state.LastPosition(); for (uint p=0; p<count; p++) { cont = (m_progress->update(p)) ; if (!cont) break; // cerr << "GCode layer " << (p+1) << " of " << count // << " offset " << printOffsetZ // << " have commands: " <<commands.size() // << " start " << start << endl;; // try { if (farthestStart) { // Vector2d randstart = layers[p]->getRandomPolygonPoint(); // start.set(randstart.x(), randstart.y()); const Vector2d fartheststart = layers[p]->getFarthestPolygonPoint(start); start.set(fartheststart.x(), fartheststart.y()); } layers[p]->MakePrintlines(start, plines, printOffsetZ, settings); // } catch (Glib::Error &e) { // error("GCode Error:", (e.what()).c_str()); // } // if (layers[p]->getPrevious() != NULL) // cerr << p << ": " <<layers[p]->LayerNo << " prev: " // << layers[p]->getPrevious()->LayerNo << endl; } // do antiooze retract for all lines: Printlines::makeAntioozeRetract(plines, settings, m_progress); vector<Command> commands; //Printlines::getCommands(plines, settings, commands, m_progress); Printlines::getCommands(plines, settings, state, m_progress); //state.AppendCommands(commands, settings.Slicing.RelativeEcode); string GcodeTxt; if (cont) gcode.MakeText (GcodeTxt, settings, m_progress); else { ClearLayers(); ClearGCode(); ClearPreview(); } // display whole layer if flat shapes // if (shapes.back()->dimensions() == 2) // gcode.layerchanges.push_back(0); m_progress->stop (_("Done")); int h = (int)state.timeused/3600; int m = ((int)state.timeused%3600)/60; int s = ((int)state.timeused-3600*h-60*m); std::ostringstream ostr; ostr << _("Time Estimation: ") ; if (h>0) ostr << h <<_("h") ; ostr <<m <<_("m") <<s <<_("s") ; double gctime = gcode.GetTimeEstimation(); if (abs(state.timeused - gctime) > 10) { h = (int)(gctime/3600); m = ((int)gctime)%3600/60; s = (int)(gctime)-3600*h-60*m; ostr << _(" / GCode Estimation: "); if (h>0) ostr << h <<_("h"); ostr<< m <<_("m") << s <<_("s") ; } double totlength = gcode.GetTotalExtruded(settings.get_boolean("Slicing","RelativeEcode")); ostr << _(" - total extruded: ") << totlength << "mm"; // TODO: ths assumes all extruders use the same filament diameter const double diam = settings.get_double("Extruder","FilamentDiameter"); const double ccm = totlength * diam * diam / 4. * M_PI / 1000 ; ostr << " = " << ccm << "cm^3 "; ostr << "(ABS~" << ccm*1.08 << "g, PLA~" << ccm*1.25 << "g)"; if (statusbar) statusbar->push(ostr.str()); else cout << ostr.str() << endl; { Glib::TimeVal now; now.assign_current_time(); const int time_used = (int) round((now - start_time).as_double()); // seconds cerr << "GCode generated in " << time_used << " seconds. " << GcodeTxt.size() << " bytes" << endl; } is_calculating=false; m_signal_gcode_changed.emit(); }
void Model::ConvertToGCode() { string GcodeTxt; string GcodeStart = settings.GCode.getStartText(); string GcodeLayer = settings.GCode.getLayerText(); string GcodeEnd = settings.GCode.getEndText(); PrintInhibitor inhibitPrint(this); m_progress.start ("Converting", Max.z); // Make Layers uint LayerNr = 0; uint LayerCount = (uint)ceil((Max.z+settings.Hardware.LayerThickness*0.5f)/settings.Hardware.LayerThickness); vector<int> altInfillLayers; settings.Slicing.GetAltInfillLayers (altInfillLayers, LayerCount); printOffset = settings.Hardware.PrintMargin; float z = Min.z + settings.Hardware.LayerThickness*0.5f; // Offset it a bit in Z, z=0 gives a empty slice because no triangles crosses this Z value gcode.clear(); float printOffsetZ = settings.Hardware.PrintMargin.z; if(settings.RaftEnable) { printOffset += Vector3f(settings.Raft.Size, settings.Raft.Size, 0); MakeRaft(printOffsetZ); } float E=0.0f; while(z<Max.z) { m_progress.update(z); for(uint o=0;o<rfo.Objects.size();o++) { for(uint f=0;f<rfo.Objects[o].files.size();f++) { STL* stl = &rfo.Objects[o].files[f].stl; // Get a pointer to the object Matrix4f T = rfo.GetSTLTransformationMatrix(o,f); Vector3f t = T.getTranslation(); t+= Vector3f(settings.Hardware.PrintMargin.x+settings.Raft.Size*settings.RaftEnable, settings.Hardware.PrintMargin.y+settings.Raft.Size*settings.RaftEnable, 0); T.setTranslation(t); CuttingPlane plane; stl->CalcCuttingPlane(z, plane, T); // output is alot of un-connected line segments with individual vertices, describing the outline float hackedZ = z; while (plane.LinkSegments (hackedZ, settings.Slicing.Optimization) == false) // If segment linking fails, re-calc a new layer close to this one, and use that. { // This happens when there's triangles missing in the input STL hackedZ+= 0.1f; stl->CalcCuttingPlane (hackedZ, plane, T); // output is alot of un-connected line segments with individual vertices } plane.SetZ (z + printOffsetZ); // inFill vector<Vector2f> infill; // CuttingPlane infillCuttingPlane; // plane.MakeContainedPlane(infillCuttingPlane); if(settings.Slicing.ShellOnly == false) { switch( settings.Slicing.ShrinkQuality ) { case SHRINK_FAST: plane.ShrinkFast(settings.Hardware.ExtrudedMaterialWidth*0.5f, settings.Slicing.Optimization, settings.Display.DisplayCuttingPlane, false, settings.Slicing.ShellCount); break; case SHRINK_LOGICK: plane.ShrinkLogick(settings.Hardware.ExtrudedMaterialWidth, settings.Slicing.Optimization, settings.Display.DisplayCuttingPlane, settings.Slicing.ShellCount); break; default: g_warning ("unknown shrinking algorithm"); break; } // check if this if a layer we should use the alternate infill distance on float infillDistance = settings.Slicing.InfillDistance; if (std::find(altInfillLayers.begin(), altInfillLayers.end(), LayerNr) != altInfillLayers.end()) { infillDistance = settings.Slicing.AltInfillDistance; } plane.CalcInFill(infill, LayerNr, infillDistance, settings.Slicing.InfillRotation, settings.Slicing.InfillRotationPrLayer, settings.Display.DisplayDebuginFill); } // Make the GCode from the plane and the infill plane.MakeGcode (infill, gcode, E, z + printOffsetZ, settings.Slicing, settings.Hardware); } } LayerNr++; z+=settings.Hardware.LayerThickness; } float AntioozeDistance = settings.Slicing.AntioozeDistance; if (!settings.Slicing.EnableAntiooze) AntioozeDistance = 0; gcode.MakeText (GcodeTxt, GcodeStart, GcodeLayer, GcodeEnd, settings.Slicing.UseIncrementalEcode, settings.Slicing.Use3DGcode, AntioozeDistance, settings.Slicing.AntioozeSpeed); m_progress.stop ("Done"); }
void Model::ConvertToGCode() { string GcodeTxt; string GcodeStart = settings.GCode.getStartText(); string GcodeLayer = settings.GCode.getLayerText(); string GcodeEnd = settings.GCode.getEndText(); PrintInhibitor inhibitPrint(this); m_progress.start (_("Converting"), Max.z); if (m_printing) { error (_("Complete print before converting"), _("Converting to GCode while printing will abort the print")); return; } // Make Layers uint LayerNr = 0; uint LayerCount = (uint)ceil((Max.z+settings.Hardware.LayerThickness*0.5f)/settings.Hardware.LayerThickness); vector<int> altInfillLayers; settings.Slicing.GetAltInfillLayers (altInfillLayers, LayerCount); printOffset = settings.Hardware.PrintMargin; // Offset it a bit in Z, z = 0 gives a empty slice because no triangle crosses this Z value float z = Min.z + settings.Hardware.LayerThickness*0.5f; gcode.clear(); float E = 0.0f; GCodeState state(gcode); float printOffsetZ = settings.Hardware.PrintMargin.z; if (settings.RaftEnable) { printOffset += Vector3f (settings.Raft.Size, settings.Raft.Size, 0); MakeRaft (state, printOffsetZ); } while(z<Max.z) { m_progress.update(z); for(uint o=0;o<rfo.Objects.size();o++) { for(uint f=0;f<rfo.Objects[o].files.size();f++) { Slicer* stl = &rfo.Objects[o].files[f].stl; // Get a pointer to the object Matrix4f T = rfo.GetSTLTransformationMatrix(o,f); Vector3f t = T.getTranslation(); t+= Vector3f(settings.Hardware.PrintMargin.x+settings.Raft.Size*settings.RaftEnable, settings.Hardware.PrintMargin.y+settings.Raft.Size*settings.RaftEnable, 0); T.setTranslation(t); CuttingPlane plane; stl->CalcCuttingPlane(z, plane, T); // output is alot of un-connected line segments with individual vertices, describing the outline float hackedZ = z; while (plane.LinkSegments (hackedZ, settings.Slicing.Optimization) == false) // If segment linking fails, re-calc a new layer close to this one, and use that. { // This happens when there's triangles missing in the input STL hackedZ+= 0.2 * settings.Hardware.LayerThickness; stl->CalcCuttingPlane (hackedZ, plane, T); // output is alot of un-connected line segments with individual vertices } // inFill vector<Vector2f> *infill = NULL; for (guint shell = 1; shell <= settings.Slicing.ShellCount; shell++) { plane.ClearShrink(); plane.SetZ (z + printOffsetZ); switch( settings.Slicing.ShrinkQuality ) { case SHRINK_FAST: plane.ShrinkFast (settings.Hardware.ExtrudedMaterialWidth, settings.Slicing.Optimization, settings.Display.DisplayCuttingPlane, false, shell); break; case SHRINK_LOGICK: plane.ShrinkLogick (settings.Hardware.ExtrudedMaterialWidth, settings.Slicing.Optimization, settings.Display.DisplayCuttingPlane, shell); break; default: g_error (_("unknown shrinking algorithm")); break; } if (shell < settings.Slicing.ShellCount ) { // no infill - just a shell ... plane.MakeGcode (state, NULL /* infill */, E, z + printOffsetZ, settings.Slicing, settings.Hardware); } else if (settings.Slicing.ShellOnly == false) { // last shell => calculate infill // check if this if a layer we should use the alternate infill distance on float infillDistance; if (settings.Slicing.SolidTopAndBottom && ( LayerNr < settings.Slicing.ShellCount || LayerNr > LayerCount-settings.Slicing.ShellCount-2 )) { infillDistance = settings.Hardware.ExtrudedMaterialWidth*settings.Hardware.ExtrusionFactor; // full fill for first layers (shell thickness) } else { infillDistance = settings.Slicing.InfillDistance; } if (std::find(altInfillLayers.begin(), altInfillLayers.end(), LayerNr) != altInfillLayers.end()) infillDistance = settings.Slicing.AltInfillDistance; infill = plane.CalcInFill (LayerNr, infillDistance, settings.Slicing.InfillRotation, settings.Slicing.InfillRotationPrLayer, settings.Display.DisplayDebuginFill); } } // Make the last shell GCode from the plane and the infill plane.MakeGcode (state, infill, E, z + printOffsetZ, settings.Slicing, settings.Hardware); delete infill; } } LayerNr++; z += settings.Hardware.LayerThickness; } float AntioozeDistance = settings.Slicing.AntioozeDistance; if (!settings.Slicing.EnableAntiooze) AntioozeDistance = 0; gcode.MakeText (GcodeTxt, GcodeStart, GcodeLayer, GcodeEnd, settings.Slicing.UseIncrementalEcode, settings.Slicing.Use3DGcode, AntioozeDistance, settings.Slicing.AntioozeSpeed); m_progress.stop (_("Done")); }