Beispiel #1
0
// 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);
		}
	}
}
Beispiel #2
0
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");
}
Beispiel #3
0
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");
}
Beispiel #4
0
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"));
}