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; }
void Model::OptimizeRotation(RFO_File *file, RFO_Object *object) { if (!file) return; // FIXME: rotate entire Objects ... file->stl.OptimizeRotation(); CalcBoundingBoxAndCenter(); }
/* 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(); }
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(); }
// 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; }
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(); } }
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")); }