// intersect lines with plane void Slicer::CalcCuttingPlane(float where, CuttingPlane &plane, const Matrix4f &T) { #if CUTTING_PLANE_DEBUG cout << "intersect with z " << where << "\n"; #endif plane.Clear(); plane.SetZ(where); Vector3f min = T*Min; Vector3f max = T*Max; plane.Min.x = min.x; plane.Min.y = min.y; plane.Max.x = max.x; plane.Max.y = max.y; Vector2f lineStart; Vector2f lineEnd; bool foundOne = false; int num_cutpoints; for (size_t i = 0; i < triangles.size(); i++) { foundOne=false; CuttingPlane::Segment line(-1,-1); num_cutpoints = triangles[i].CutWithPlane(where, T, lineStart, lineEnd); if (num_cutpoints>0) line.start = plane.RegisterPoint(lineStart); if (num_cutpoints>1) line.end = plane.RegisterPoint(lineEnd); // Check segment normal against triangle normal. Flip segment, as needed. if (line.start != -1 && line.end != -1 && line.end != line.start) // if we found a intersecting triangle { Vector3f Norm = triangles[i].Normal; Vector2f triangleNormal = Vector2f(Norm.x, Norm.y); Vector2f segmentNormal = (lineEnd - lineStart).normal(); triangleNormal.normalise(); segmentNormal.normalise(); if( (triangleNormal-segmentNormal).lengthSquared() > 0.2f) // if normals does not align, flip the segment line.Swap(); plane.AddLine(line); } } }
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 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; uint LayerCount = (uint)ceil((Max.z+LayerThickness*0.5f)/LayerThickness); vector<int> altInfillLayers; GetAltInfillLayers(altInfillLayers, LayerCount); 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 printOffsetZ=PrintMargin.z; if(RaftEnable) { printOffset += Vector3f(RaftSize, RaftSize, 0); MakeRaft(printOffsetZ); } float E=0.0f; while(z<Max.z) { 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, 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(ShellOnly == false) { switch( m_ShrinkQuality ) { case SHRINK_FAST: plane.ShrinkFast(ExtrudedMaterialWidth*0.5f, Optimization, DisplayCuttingPlane, false, ShellCount); break; case SHRINK_LOGICK: plane.ShrinkLogick(ExtrudedMaterialWidth, Optimization, DisplayCuttingPlane, ShellCount); break; } // check if this if a layer we should use the alternate infill distance on float infillDistance = InfillDistance; if (std::find(altInfillLayers.begin(), altInfillLayers.end(), LayerNr) != altInfillLayers.end()) { infillDistance = AltInfillDistance; } plane.CalcInFill(infill, LayerNr, infillDistance, InfillRotation, InfillRotationPrLayer, DisplayDebuginFill); } // Make the GCode from the plane and the infill plane.MakeGcode(infill, gcode, E, z+printOffsetZ, MinPrintSpeedXY, MaxPrintSpeedXY, MinPrintSpeedZ, MaxPrintSpeedZ, DistanceToReachFullSpeed, extrusionFactor, UseIncrementalEcode, Use3DGcode, EnableAcceleration); } } LayerNr++; z+=LayerThickness; } GcodeTxt.clear(); if (!EnableAntiooze) { AntioozeDistance = 0; } gcode.MakeText(GcodeTxt, GcodeStart, GcodeLayer, GcodeEnd, UseIncrementalEcode, Use3DGcode, AntioozeDistance, AntioozeSpeed); gui->ProgressBar->label("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); // 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")); }