예제 #1
0
RFO_File* Model::AddStl(RFO_Object *parent, STL stl, string filename)
{
  RFO_File *file, *lastfile;

  if (!parent) {
    if (rfo.Objects.size() <= 0)
      rfo.newObject();
    parent = &rfo.Objects.back();
  }
  g_assert (parent != NULL);

  size_t found = filename.find_last_of("/\\");
  lastfile = NULL;
  if (parent->files.size() > 0)
    lastfile = &parent->files.back();

  Gtk::TreePath path = rfo.createFile (parent, stl, filename.substr(found+1));
  m_signal_stl_added.emit (path);

  file = &parent->files.back();
  if (lastfile) {
    Vector3f p = lastfile->transform3D.transform.getTranslation();
    Vector3f size = lastfile->stl.Max - lastfile->stl.Min;
    p.x += size.x + 5.0f; // 5mm space
    file->transform3D.transform.setTranslation(p);
  }

  CalcBoundingBoxAndCenter();

  return file;
}
예제 #2
0
void Model::OptimizeRotation(RFO_File *file, RFO_Object *object)
{
  if (!file)
    return; // FIXME: rotate entire Objects ...

  file->stl.OptimizeRotation();
  CalcBoundingBoxAndCenter();
}
예제 #3
0
/* Scales the object on changes of the scale slider */
void Model::ScaleObject(RFO_File *file, RFO_Object *object, double scale)
{
  if (!file)
    return;

  file->stl.Scale(scale);
  CalcBoundingBoxAndCenter();
}
예제 #4
0
void Model::RotateObject(RFO_File *file, RFO_Object *object, Vector4f rotate)
{
  Vector3f rot(rotate.x, rotate.y, rotate.z);

  if (!file)
    return; // FIXME: rotate entire Objects ...

  file->stl.RotateObject(rot, rotate.w);
  CalcBoundingBoxAndCenter();
}
예제 #5
0
// rearrange unselected shapes in random sequence
bool Model::AutoArrange(vector<Gtk::TreeModel::Path> &path)
{
  // all shapes
  vector<Shape*>   allshapes;
  vector<Matrix4d> transforms;
  objtree.get_all_shapes(allshapes, transforms);

  // selected shapes
  vector<Shape*>   selshapes;
  vector<Matrix4d> seltransforms;
  objtree.get_selected_shapes(path, selshapes, seltransforms);

  // get unselected shapes
  vector<Shape*>   unselshapes;
  vector<Matrix4d> unseltransforms;

  for(uint s=0; s < allshapes.size(); s++) {
    bool issel = false;
    for(uint ss=0; ss < selshapes.size(); ss++)
      if (selshapes[ss] == allshapes[s]) {
	issel = true; break;
      }
    if (!issel) {
      unselshapes.    push_back(allshapes[s]);
      unseltransforms.push_back(transforms[s]);
    }
  }

  // find place for unselected shapes
  int num = unselshapes.size();
  vector<int> rand_seq(num,1); // 1,1,1...
  partial_sum(rand_seq.begin(), rand_seq.end(), rand_seq.begin()); // 1,2,3,...,N

  Glib::TimeVal timeval;
  timeval.assign_current_time();
  srandom((unsigned long)(timeval.as_double()));
  random_shuffle(rand_seq.begin(), rand_seq.end()); // shuffle

  for(int s=0; s < num; s++) {
    int index = rand_seq[s]-1;
    // use selshapes as vector to fill up
    Vector3d trans = FindEmptyLocation(selshapes, seltransforms, unselshapes[index]);
    selshapes.push_back(unselshapes[index]);
    seltransforms.push_back(unseltransforms[index]); // basic transform, not shape
    selshapes.back()->transform3D.move(trans);
    CalcBoundingBoxAndCenter();
  }
  ModelChanged();
  return true;
}
예제 #6
0
void Model::ModelChanged()
{
  if (m_inhibit_modelchange) return;
  //printer.update_temp_poll_interval(); // necessary?
  if (!is_printing) {
    CalcBoundingBoxAndCenter();
    Infill::clearPatterns();
    if ( layers.size()>0 || m_previewGCode.size()>0 || m_previewLayer ) {
      ClearGCode();
      ClearLayers();
    }
    setCurrentPrintingLine(0);
    m_model_changed.emit();
  }
}
예제 #7
0
void Model::Slice()
{
  vector<Shape*> shapes;
  vector<Matrix4d> transforms;

  if (settings.get_boolean("Slicing","SelectedOnly"))
    objtree.get_selected_shapes(m_current_selectionpath, shapes, transforms);
  else
    objtree.get_all_shapes(shapes,transforms);

  if (shapes.size() == 0) return;

  assert(shapes.size() == transforms.size());

  CalcBoundingBoxAndCenter(settings.get_boolean("Slicing","SelectedOnly"));

  for (uint i = 0; i<transforms.size(); i++)
    transforms[i] = settings.getBasicTransformation(transforms[i]);

  assert(shapes.size() == transforms.size());

  int LayerNr = 0;
  bool varSlicing = settings.get_boolean("Slicing","Varslicing");

  uint max_skins = max(1, settings.get_integer("Slicing","Skins"));
  double thickness = (double)settings.get_double("Slicing","LayerThickness");
  double skin_thickness = thickness / max_skins;
  uint skins = max_skins; // probably variable

  // - Start at z~=0, cut off everything below
  // - Offset it a bit in Z, z = 0 gives a empty slice because no triangle crosses this Z value
  double minZ = thickness * settings.get_double("Slicing","FirstLayerHeight");// + Min.z;
  Vector3d volume = settings.getPrintVolume();
  double maxZ = min(Max.z(), volume.z() - settings.getPrintMargin().z());

  double max_gradient = 0;
  double supportangle = settings.get_double("Slicing","SupportAngle")*M_PI/180.;
  if (!settings.get_boolean("Slicing","Support")) supportangle = -1;

  m_progress->set_terminal_output(settings.get_boolean("Display","TerminalProgress"));
  m_progress->start (_("Slicing"), maxZ);
  // for (vector<Layer *>::iterator pIt = layers.begin();
  //      pIt != layers. end(); pIt++)
  //   delete *pIt;
  ClearLayers();

  bool flatshapes = shapes.front()->dimensions() == 2;
  if (flatshapes) {
    layers.resize(1);
    layers[0] = new Layer(lastlayer, 0, thickness  , 1);
    lastlayer = layers[0];
    layers[0]->setZ(0); // set to real z
    for (uint nshape= 0; nshape < shapes.size(); nshape++) {
      layers[0]->addShape(transforms[nshape], *shapes[nshape],  0, max_gradient, -1);
    }
    return;
  }

  int progress_steps=max(1,(int)(maxZ/thickness/100.));

  if ((varSlicing && skins > 1) ||
      (settings.get_boolean("Slicing","BuildSerial") && shapes.size() > 1))
  {
    // have skins and/or serial build, so can't parallelise
    uint currentshape   = 0;
    double serialheight = maxZ; // settings.Slicing.SerialBuildHeight;
    double z            = minZ;
    double shape_z      = z;
    double max_shape_z  = z + serialheight;
    Layer * layer = new Layer(lastlayer, LayerNr, thickness, 1); // first layer no skins
    layer->setZ(shape_z);
    LayerNr = 1;
    int new_polys=0;
    bool cont = true;
    while(cont && z < maxZ)
      {
        shape_z = z;
        max_shape_z = min(shape_z + serialheight, maxZ);
        while ( cont && currentshape < shapes.size() && shape_z <= max_shape_z ) {
  	if (LayerNr%progress_steps==0) cont = m_progress->update(shape_z);
  	layer->setZ(shape_z); // set to real z
  	if (shape_z == minZ) { // the layer is on the platform
  	  layer->LayerNo = 0;
  	  layer->setSkins(1);
  	  LayerNr = 1;
  	}
  	new_polys = layer->addShape(transforms[currentshape], *shapes[currentshape],
  				    shape_z, max_gradient, supportangle);
  	// cerr << "Z="<<z<<", shapez="<< shape_z << ", shape "<<currentshape
  	//      << " of "<< shapes.size()<< " polys:" << new_polys<<endl;
  	if (shape_z >= max_shape_z) { // next shape, reset z
  	  currentshape++;
  	  shape_z = z;
  	} else {  // next z, same shape
  	  if (varSlicing && LayerNr!=0) {
  	    // higher gradient -> slice thinner with fewer skin divisions
  	    skins = max_skins-(uint)(max_skins* max_gradient);
  	    thickness = skin_thickness*skins;
  	  }
  	  shape_z += thickness;
  	  max_gradient = 0;
  	  if (new_polys > -1){
  	    layers.push_back(layer);
  	    lastlayer = layer;
  	    layer = new Layer(lastlayer, LayerNr++, thickness, skins);
  	  }
  	}
        }
        //thickness = max_thickness-(max_thickness-min_thickness)*max_gradient;
        if (currentshape < shapes.size()-1) { // reached max_shape_z, next shape
  	currentshape++;
        } else { // end of shapes
  	if (new_polys > -1){
  	  if (varSlicing) {
  	    skins = max_skins-(uint)(max_skins* max_gradient);
  	    thickness = skin_thickness*skins;
  	  }
  	  layers.push_back(layer);
  	  lastlayer = layer;
  	  layer = new Layer(lastlayer, LayerNr++, thickness, skins);
  	}
  	z = max_shape_z + thickness;
  	currentshape = 0; // all shapes again
        }
        max_gradient=0;
        //cerr << "    Z="<<z << "Max.z="<<Max.z<<endl;
      }
    delete layer; // have made one more than needed
    return;
  }

  // simple case, can do multihreading

  int num_layers = (int)ceil((maxZ - minZ) / thickness);
  layers.resize(num_layers);
  int nlayer;
  bool cont = true;

#ifdef _OPENMP
  #pragma omp parallel for schedule(dynamic)
#endif
  for (nlayer = 0; nlayer < num_layers; nlayer++) {
    double z = minZ + thickness * nlayer;
    if (nlayer%progress_steps==0) {
#ifdef _OPENMP
	#pragma omp critical(updateProgress)
	{
	    cont = (m_progress->update(z));
	    #pragma omp flush (cont)
	}
#else
        cont = (m_progress->update(z));
#endif
    }
#ifdef _OPENMP
    #pragma omp flush (cont)
    if (!cont) continue;
#else
    if (!cont) break;
#endif
    Layer * layer = new Layer(NULL, nlayer, thickness, nlayer>0?skins:1);
    layer->setZ(z); // set to real z
    for (uint nshape= 0; nshape < shapes.size(); nshape++) {
      layer->addShape(transforms[nshape], *shapes[nshape],
		      z, max_gradient, supportangle);
    }
    layers[nlayer] = layer;
  }
  if (!cont)
    ClearLayers();

#ifdef _OPENMP
    //std::sort(layers.begin(), layers.end(), layersort);
#endif

  for (uint nlayer = 1; nlayer < layers.size(); nlayer++) {
    layers[nlayer]->setPrevious(layers[nlayer-1]);
    assert(layers[nlayer]->Z > layers[nlayer-1]->Z);
  }
  if (layers.size()>0)
	lastlayer = layers.back();

  // shapes.clear();
  //m_progress->stop (_("Done"));
}