mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/Prusa3d/Slic3r
This commit is contained in:
		
						commit
						9722bcdd75
					
				
					 15 changed files with 144 additions and 65 deletions
				
			
		|  | @ -661,6 +661,23 @@ void ModelObject::delete_volume(size_t idx) | |||
|     ModelVolumePtrs::iterator i = this->volumes.begin() + idx; | ||||
|     delete *i; | ||||
|     this->volumes.erase(i); | ||||
| 
 | ||||
|     if (this->volumes.size() == 1) | ||||
|     { | ||||
|         // only one volume left
 | ||||
|         // center it and update the instances accordingly
 | ||||
|         // rationale: the volume may be shifted with respect to the object center and this may lead to wrong rotation and scaling 
 | ||||
|         // when modifying the instance matrix of the derived GLVolume
 | ||||
|         ModelVolume* v = this->volumes.front(); | ||||
|         v->center_geometry(); | ||||
|         const Vec3d& vol_offset = v->get_offset(); | ||||
|         for (ModelInstance* inst : this->instances) | ||||
|         { | ||||
|             inst->set_offset(inst->get_offset() + inst->get_matrix(true) * vol_offset); | ||||
|         } | ||||
|         v->set_offset(Vec3d::Zero()); | ||||
|     } | ||||
| 
 | ||||
|     this->invalidate_bounding_box(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2471,15 +2471,6 @@ void PrintConfigDef::init_sla_params() | |||
|     def->min = 0; | ||||
|     def->default_value = new ConfigOptionFloat(0.2); | ||||
| 
 | ||||
|     def = this->add("support_head_back_radius", coFloat); | ||||
|     def->label = L("Support head back radius"); | ||||
|     def->category = L("Supports"); | ||||
|     def->tooltip = L("Radius of the back side of the 3d arrow"); | ||||
|     def->sidetext = L("mm"); | ||||
|     def->cli = ""; | ||||
|     def->min = 0; | ||||
|     def->default_value = new ConfigOptionFloat(0.5); | ||||
| 
 | ||||
|     def = this->add("support_head_width", coFloat); | ||||
|     def->label = L("Support head width"); | ||||
|     def->category = L("Supports"); | ||||
|  | @ -2496,7 +2487,19 @@ void PrintConfigDef::init_sla_params() | |||
|     def->sidetext = L("mm"); | ||||
|     def->cli = ""; | ||||
|     def->min = 0; | ||||
|     def->default_value = new ConfigOptionFloat(0.8); | ||||
|     def->default_value = new ConfigOptionFloat(0.5); | ||||
| 
 | ||||
|     def = this->add("support_pillar_widening_factor", coFloat); | ||||
|     def->label = L("Pillar widening factor"); | ||||
|     def->category = L("Supports"); | ||||
|     def->tooltip = L("Merging bridges or pillars into another pillars can " | ||||
|                      "increase the radius. Zero means no increase, one means " | ||||
|                      "full increase."); | ||||
|     def->sidetext = L(""); | ||||
|     def->cli = ""; | ||||
|     def->min = 0; | ||||
|     def->max = 1.0; | ||||
|     def->default_value = new ConfigOptionFloat(0.0); | ||||
| 
 | ||||
|     def = this->add("support_base_radius", coFloat); | ||||
|     def->label = L("Support base radius"); | ||||
|  |  | |||
|  | @ -913,20 +913,18 @@ public: | |||
|     // How much the pinhead has to penetrate the model surface
 | ||||
|     ConfigOptionFloat support_head_penetration /*= 0.2*/; | ||||
| 
 | ||||
|     // Radius of the back side of the 3d arrow. TODO: consider renaming this
 | ||||
|     // to actual pillar radius, because that's what it boils down to.
 | ||||
|     ConfigOptionFloat support_head_back_radius /*= 0.5*/; | ||||
| 
 | ||||
|     // Width in mm from the back sphere center to the front sphere center.
 | ||||
|     ConfigOptionFloat support_head_width /*= 1.0*/; | ||||
| 
 | ||||
|     // Radius in mm of the support pillars.
 | ||||
|     // TODO: This parameter is questionable. The pillar radius will be dynamic in
 | ||||
|     // nature. Merged pillars will have an increased thickness. This parameter
 | ||||
|     // may serve as the maximum radius, or maybe an increase when two are merged
 | ||||
|     // The default radius will be derived from head_back_radius_mm
 | ||||
|     ConfigOptionFloat support_pillar_radius /*= 0.8*/; | ||||
| 
 | ||||
|     // TODO: unimplemented at the moment. This coefficient will have an impact
 | ||||
|     // when bridges and pillars are merged. The resulting pillar should be a bit
 | ||||
|     // thicker than the ones merging into it. How much thicker? I don't know
 | ||||
|     // but it will be derived from this value.
 | ||||
|     ConfigOptionFloat support_pillar_widening_factor; | ||||
| 
 | ||||
|     // Radius in mm of the pillar base.
 | ||||
|     ConfigOptionFloat support_base_radius /*= 2.0*/; | ||||
| 
 | ||||
|  | @ -968,9 +966,9 @@ protected: | |||
|         OPT_PTR(supports_enable); | ||||
|         OPT_PTR(support_head_front_radius); | ||||
|         OPT_PTR(support_head_penetration); | ||||
|         OPT_PTR(support_head_back_radius); | ||||
|         OPT_PTR(support_head_width); | ||||
|         OPT_PTR(support_pillar_radius); | ||||
|         OPT_PTR(support_pillar_widening_factor); | ||||
|         OPT_PTR(support_base_radius); | ||||
|         OPT_PTR(support_base_height); | ||||
|         OPT_PTR(support_critical_angle); | ||||
|  |  | |||
|  | @ -309,7 +309,7 @@ struct Head { | |||
|     } | ||||
| 
 | ||||
|     double request_pillar_radius(double radius) const { | ||||
|         const double rmax = r_back_mm /* * 0.65*/ ; | ||||
|         const double rmax = r_back_mm; | ||||
|         return radius > 0 && radius < rmax ? radius : rmax; | ||||
|     } | ||||
| }; | ||||
|  | @ -929,6 +929,9 @@ bool SLASupportTree::generate(const PointSet &points, | |||
|                               const SupportConfig &cfg, | ||||
|                               const Controller &ctl) | ||||
| { | ||||
|     // If there are no input points there is no point in doing anything
 | ||||
|     if(points.rows() == 0) return false; | ||||
| 
 | ||||
|     PointSet filtered_points;       // all valid support points
 | ||||
|     PointSet head_positions;        // support points with pinhead
 | ||||
|     PointSet head_normals;          // head normals
 | ||||
|  | @ -1183,7 +1186,7 @@ bool SLASupportTree::generate(const PointSet &points, | |||
| 
 | ||||
|         // If the pillars are so close that they touch each other,
 | ||||
|         // there is no need to bridge them together.
 | ||||
|         if(pillar_dist > 2*cfg.pillar_radius_mm && | ||||
|         if(pillar_dist > 2*cfg.head_back_radius_mm && | ||||
|            bridge_distance < cfg.max_bridge_length_mm) | ||||
|             while(sj(Z) > pillar.endpoint(Z) && | ||||
|                   ej(Z) > nextpillar.endpoint(Z)) | ||||
|  | @ -1222,7 +1225,7 @@ bool SLASupportTree::generate(const PointSet &points, | |||
|             Result& result) | ||||
|     { | ||||
|         const double hbr = cfg.head_back_radius_mm; | ||||
|         const double pradius = cfg.pillar_radius_mm; | ||||
|         const double pradius = cfg.head_back_radius_mm; | ||||
|         const double maxbridgelen = cfg.max_bridge_length_mm; | ||||
|         const double gndlvl = result.ground_level; | ||||
| 
 | ||||
|  | @ -1475,7 +1478,7 @@ bool SLASupportTree::generate(const PointSet &points, | |||
| 
 | ||||
|             result.add_pillar(idx, | ||||
|                 Vec3d{headend(X), headend(Y), headend(Z) - gh + hl}, | ||||
|                 cfg.pillar_radius_mm | ||||
|                 cfg.head_back_radius_mm | ||||
|             ).base = base_head.mesh; | ||||
|         } | ||||
|     }; | ||||
|  | @ -1490,7 +1493,7 @@ bool SLASupportTree::generate(const PointSet &points, | |||
|         // For now we will just generate smaller headless sticks with a sharp
 | ||||
|         // ending point that connects to the mesh surface.
 | ||||
| 
 | ||||
|         const double R = 0.5*cfg.pillar_radius_mm; | ||||
|         const double R = cfg.headless_pillar_radius_mm; | ||||
|         const double HWIDTH_MM = R/3; | ||||
| 
 | ||||
|         // We will sink the pins into the model surface for a distance of 1/3 of
 | ||||
|  | @ -1619,10 +1622,7 @@ bool SLASupportTree::generate(const PointSet &points, | |||
|     return pc == ABORT; | ||||
| } | ||||
| 
 | ||||
| SLASupportTree::SLASupportTree(): m_impl(new Impl()) | ||||
| { | ||||
| 
 | ||||
| } | ||||
| SLASupportTree::SLASupportTree(): m_impl(new Impl()) {} | ||||
| 
 | ||||
| const TriangleMesh &SLASupportTree::merged_mesh() const | ||||
| { | ||||
|  |  | |||
|  | @ -41,13 +41,16 @@ struct SupportConfig { | |||
|     // Width in mm from the back sphere center to the front sphere center.
 | ||||
|     double head_width_mm = 1.0; | ||||
| 
 | ||||
|     // Radius in mm of the support pillars.
 | ||||
|     // Warning: this value will be at most 65% of head_back_radius_mm
 | ||||
|     // TODO: This parameter is invalid. The pillar radius will be dynamic in
 | ||||
|     // nature. Merged pillars will have an increased thickness. This parameter
 | ||||
|     // may serve as the maximum radius, or maybe an increase when two are merged
 | ||||
|     // The default radius will be derived from head_back_radius_mm
 | ||||
|     double pillar_radius_mm = 0.8; | ||||
|     // Radius in mm of the support pillars. The actual radius of the pillars
 | ||||
|     // beginning with a head will not be higher than head_back_radius but the
 | ||||
|     // headless pillars will have half of this value.
 | ||||
|     double headless_pillar_radius_mm = 0.4; | ||||
| 
 | ||||
|     // TODO: unimplemented at the moment. This coefficient will have an impact
 | ||||
|     // when bridges and pillars are merged. The resulting pillar should be a bit
 | ||||
|     // thicker than the ones merging into it. How much thicker? I don't know
 | ||||
|     // but it will be derived from this value.
 | ||||
|     double pillar_widening_factor = 0.5; | ||||
| 
 | ||||
|     // Radius in mm of the pillar base.
 | ||||
|     double base_radius_mm = 2.0; | ||||
|  |  | |||
|  | @ -84,6 +84,7 @@ size_t SpatIndex::size() const | |||
| } | ||||
| 
 | ||||
| PointSet normals(const PointSet& points, const EigenMesh3D& mesh) { | ||||
|     if(points.rows() == 0 || mesh.V.rows() == 0 || mesh.F.rows() == 0) return {}; | ||||
| #ifdef IGL_COMPATIBLE | ||||
|     Eigen::VectorXd dists; | ||||
|     Eigen::VectorXi I; | ||||
|  | @ -108,7 +109,7 @@ PointSet normals(const PointSet& points, const EigenMesh3D& mesh) { | |||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| #else | ||||
| #else // TODO:  do something on 32 bit windows
 | ||||
|     return {}; | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -458,13 +458,16 @@ void SLAPrint::process() | |||
|             SLAPrintObjectConfig& c = po.m_config; | ||||
| 
 | ||||
|             scfg.head_front_radius_mm = c.support_head_front_radius.getFloat(); | ||||
|             scfg.head_back_radius_mm = c.support_head_back_radius.getFloat(); | ||||
|             scfg.head_back_radius_mm = c.support_pillar_radius.getFloat(); | ||||
|             scfg.head_penetration_mm = c.support_head_penetration.getFloat(); | ||||
|             scfg.head_width_mm = c.support_head_width.getFloat(); | ||||
|             scfg.object_elevation_mm = c.support_object_elevation.getFloat(); | ||||
|             scfg.tilt = c.support_critical_angle.getFloat() * PI / 180.0 ; | ||||
|             scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat(); | ||||
|             scfg.pillar_radius_mm = c.support_pillar_radius.getFloat(); | ||||
|             scfg.headless_pillar_radius_mm = 0.75*c.support_pillar_radius.getFloat(); | ||||
|             scfg.pillar_widening_factor = c.support_pillar_widening_factor.getFloat(); | ||||
|             scfg.base_radius_mm = c.support_base_radius.getFloat(); | ||||
|             scfg.base_height_mm = c.support_base_height.getFloat(); | ||||
| 
 | ||||
|             sla::Controller ctl; | ||||
| 
 | ||||
|  | @ -521,11 +524,6 @@ void SLAPrint::process() | |||
|             if(elevation < pad_h) sla::base_plate(trmesh, bp, | ||||
|                                                   float(pad_h), float(lh)); | ||||
| 
 | ||||
|             std::cout << "Mesh is empty: " << trmesh.empty() << std::endl; | ||||
|             std::cout << "Pad height: " << pad_h << std::endl; | ||||
|             std::cout << "Elevation " << elevation << std::endl; | ||||
|             std::cout << "Pad plate vertices: " << bp.size() << std::endl; | ||||
| 
 | ||||
|             po.m_supportdata->support_tree_ptr->add_pad(bp, wt, h, md, er); | ||||
|         } | ||||
|     }; | ||||
|  |  | |||
|  | @ -1320,10 +1320,12 @@ void GLCanvas3D::Selection::add_all() | |||
|         return; | ||||
| 
 | ||||
|     m_mode = Instance; | ||||
|     clear(); | ||||
| 
 | ||||
|     for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) | ||||
|     { | ||||
|         _add_volume(i); | ||||
|         if (!(*m_volumes)[i]->is_wipe_tower) | ||||
|             _add_volume(i); | ||||
|     } | ||||
| 
 | ||||
|     _update_type(); | ||||
|  | @ -1399,6 +1401,12 @@ bool GLCanvas3D::Selection::is_single_full_instance() const | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool GLCanvas3D::Selection::is_from_single_object() const | ||||
| { | ||||
|     int idx = get_object_idx(); | ||||
|     return (0 <= idx) && (idx < 1000); | ||||
| } | ||||
| 
 | ||||
| int GLCanvas3D::Selection::get_object_idx() const | ||||
| { | ||||
|     return (m_cache.content.size() == 1) ? m_cache.content.begin()->first : -1; | ||||
|  | @ -1455,7 +1463,7 @@ void GLCanvas3D::Selection::translate(const Vec3d& displacement) | |||
|             (*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement); | ||||
|         else if (m_mode == Volume) | ||||
|         { | ||||
|             Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_volume_rotation_matrix()).inverse() * displacement; | ||||
|             Vec3d local_displacement = m_cache.volumes_data[i].get_instance_rotation_matrix().inverse() * displacement; | ||||
|             (*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); | ||||
|         } | ||||
| #else | ||||
|  | @ -1924,9 +1932,17 @@ void GLCanvas3D::Selection::_update_type() | |||
|                 unsigned int volumes_count = (unsigned int)model_object->volumes.size(); | ||||
|                 unsigned int instances_count = (unsigned int)model_object->instances.size(); | ||||
|                 if (volumes_count * instances_count == 1) | ||||
|                 { | ||||
|                     m_type = SingleFullObject; | ||||
|                     // ensures the correct mode is selected
 | ||||
|                     m_mode = Instance; | ||||
|                 } | ||||
|                 else if (volumes_count == 1) // instances_count > 1
 | ||||
|                 { | ||||
|                     m_type = SingleFullInstance; | ||||
|                     // ensures the correct mode is selected
 | ||||
|                     m_mode = Instance; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     m_type = SingleVolume; | ||||
|  | @ -1950,11 +1966,19 @@ void GLCanvas3D::Selection::_update_type() | |||
|                 unsigned int instances_count = (unsigned int)model_object->instances.size(); | ||||
|                 unsigned int selected_instances_count = (unsigned int)m_cache.content.begin()->second.size(); | ||||
|                 if (volumes_count * instances_count == (unsigned int)m_list.size()) | ||||
|                 { | ||||
|                     m_type = SingleFullObject; | ||||
|                     // ensures the correct mode is selected
 | ||||
|                     m_mode = Instance; | ||||
|                 } | ||||
|                 else if (selected_instances_count == 1) | ||||
|                 { | ||||
|                     if (volumes_count == (unsigned int)m_list.size()) | ||||
|                     { | ||||
|                         m_type = SingleFullInstance; | ||||
|                         // ensures the correct mode is selected
 | ||||
|                         m_mode = Instance; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         unsigned int modifiers_count = 0; | ||||
|  | @ -1977,7 +2001,11 @@ void GLCanvas3D::Selection::_update_type() | |||
|                     } | ||||
|                 } | ||||
|                 else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size())) | ||||
|                 { | ||||
|                     m_type = MultipleFullInstance; | ||||
|                     // ensures the correct mode is selected
 | ||||
|                     m_mode = Instance; | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  | @ -1990,7 +2018,11 @@ void GLCanvas3D::Selection::_update_type() | |||
|                         sels_cntr += volumes_count * instances_count; | ||||
|                 } | ||||
|                 if (sels_cntr == (unsigned int)m_list.size()) | ||||
|                 { | ||||
|                     m_type = MultipleFullObject; | ||||
|                     // ensures the correct mode is selected
 | ||||
|                     m_mode = Instance; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -2002,66 +2034,84 @@ void GLCanvas3D::Selection::_update_type() | |||
|         v->disabled = requires_disable ? (v->object_idx() != object_idx) || (v->instance_idx() != instance_idx) : false; | ||||
|     } | ||||
| 
 | ||||
|     std::cout << "Selection: "; | ||||
|     std::cout << "mode: "; | ||||
|     switch (m_mode) | ||||
|     { | ||||
|     case Volume: | ||||
|     { | ||||
|         std::cout << "Volume"; | ||||
|         break; | ||||
|     } | ||||
|     case Instance: | ||||
|     { | ||||
|         std::cout << "Instance"; | ||||
|         break; | ||||
|     } | ||||
|     } | ||||
| 
 | ||||
|     std::cout << " - type: "; | ||||
| 
 | ||||
|     switch (m_type) | ||||
|     { | ||||
|     case Invalid: | ||||
|     { | ||||
|         std::cout << "selection type: Invalid" << std::endl; | ||||
|         std::cout << "Invalid" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case Empty: | ||||
|     { | ||||
|         std::cout << "selection type: Empty" << std::endl; | ||||
|         std::cout << "Empty" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case WipeTower: | ||||
|     { | ||||
|         std::cout << "selection type: WipeTower" << std::endl; | ||||
|         std::cout << "WipeTower" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case SingleModifier: | ||||
|     { | ||||
|         std::cout << "selection type: SingleModifier" << std::endl; | ||||
|         std::cout << "SingleModifier" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case MultipleModifier: | ||||
|     { | ||||
|         std::cout << "selection type: MultipleModifier" << std::endl; | ||||
|         std::cout << "MultipleModifier" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case SingleVolume: | ||||
|     { | ||||
|         std::cout << "selection type: SingleVolume" << std::endl; | ||||
|         std::cout << "SingleVolume" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case MultipleVolume: | ||||
|     { | ||||
|         std::cout << "selection type: MultipleVolume" << std::endl; | ||||
|         std::cout << "MultipleVolume" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case SingleFullObject: | ||||
|     { | ||||
|         std::cout << "selection type: SingleFullObject" << std::endl; | ||||
|         std::cout << "SingleFullObject" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case MultipleFullObject: | ||||
|     { | ||||
|         std::cout << "selection type: MultipleFullObject" << std::endl; | ||||
|         std::cout << "MultipleFullObject" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case SingleFullInstance: | ||||
|     { | ||||
|         std::cout << "selection type: SingleFullInstance" << std::endl; | ||||
|         std::cout << "SingleFullInstance" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case MultipleFullInstance: | ||||
|     { | ||||
|         std::cout << "selection type: MultipleFullInstance" << std::endl; | ||||
|         std::cout << "MultipleFullInstance" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     case Mixed: | ||||
|     { | ||||
|         std::cout << "selection type: Mixed" << std::endl; | ||||
|         std::cout << "Mixed" << std::endl; | ||||
|         break; | ||||
|     } | ||||
|     } | ||||
|  | @ -3943,7 +3993,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re | |||
| 					int extruder_id = mvs->model_volume->extruder_id(); | ||||
| 					if (extruder_id != -1) | ||||
| 						volume->extruder_id = extruder_id; | ||||
| 				} | ||||
| 
 | ||||
|                     // updates volumes transformations
 | ||||
|                     volume->set_instance_transformation(mvs->model_volume->get_object()->instances[volume->instance_idx()]->get_transformation()); | ||||
|                     volume->set_volume_transformation(mvs->model_volume->get_transformation()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -4016,6 +4070,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re | |||
|             size_t idx = 0; | ||||
|             const SLAPrint *sla_print = this->sla_print(); | ||||
|             for (const SLAPrintObject *print_object : sla_print->objects()) { | ||||
|                 std::cout << "Current elevation: "<< print_object->get_current_elevation() << std::endl; | ||||
|                 SLASupportState   &state        = sla_support_state[idx ++]; | ||||
|                 const ModelObject *model_object = print_object->model_object(); | ||||
|                 // Find an index of the ModelObject
 | ||||
|  |  | |||
|  | @ -502,7 +502,7 @@ public: | |||
|         bool is_multiple_volume() const { return m_type == MultipleVolume; } | ||||
|         bool is_mixed() const { return m_type == Mixed; } | ||||
|         bool is_from_single_instance() const { return get_instance_idx() != -1; } | ||||
|         bool is_from_single_object() const { return get_object_idx() != -1; } | ||||
|         bool is_from_single_object() const; | ||||
| 
 | ||||
|         bool contains_volume(unsigned int volume_idx) const { return std::find(m_list.begin(), m_list.end(), volume_idx) != m_list.end(); } | ||||
| 
 | ||||
|  |  | |||
|  | @ -333,7 +333,7 @@ void ObjectList::key_event(wxKeyEvent& event) | |||
|         printf("WXK_BACK\n"); | ||||
|         remove(); | ||||
|     } | ||||
|     else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) | ||||
|     else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT)) | ||||
|         select_item_all_children(); | ||||
|     else | ||||
|         event.Skip(); | ||||
|  | @ -1230,7 +1230,8 @@ void ObjectList::delete_from_model_and_list(const std::vector<ItemForDelete>& it | |||
|             m_objects_model->Delete(m_objects_model->GetItemById(item->obj_idx)); | ||||
|         } | ||||
|         else { | ||||
|             del_subobject_from_object(item->obj_idx, item->sub_obj_idx, item->type); | ||||
|             if (!del_subobject_from_object(item->obj_idx, item->sub_obj_idx, item->type)) | ||||
|                 continue; | ||||
|             if (item->type&itVolume) | ||||
|             { | ||||
|                 m_objects_model->Delete(m_objects_model->GetItemByVolumeId(item->obj_idx, item->sub_obj_idx)); | ||||
|  | @ -1305,7 +1306,7 @@ void ObjectList::remove() | |||
|     for (auto& item : sels) | ||||
|     { | ||||
|         if (m_objects_model->GetParent(item) == wxDataViewItem(0)) | ||||
|             wxGetApp().plater()->remove(m_objects_model->GetIdByItem(item)); | ||||
|             delete_from_model_and_list(itObject, m_objects_model->GetIdByItem(item), -1); | ||||
|         else | ||||
|             del_subobject_item(item); | ||||
|     } | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include "GUI_ObjectSettings.hpp" | ||||
| #include "GLCanvas3D.hpp" | ||||
| 
 | ||||
| class wxStaticText; | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  |  | |||
|  | @ -2200,7 +2200,7 @@ bool Plater::priv::init_object_menu() | |||
|     wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "shape_ungroup.png"); | ||||
| 
 | ||||
|     // Add the automatic rotation sub-menu
 | ||||
|     item_sla_autorot = append_menu_item(&object_menu, wxID_ANY, _(L("Optimize orientation\t+")), _(L("Optimize the rotation of the object for better print results.")), | ||||
|     item_sla_autorot = append_menu_item(&object_menu, wxID_ANY, _(L("Optimize orientation")), _(L("Optimize the rotation of the object for better print results.")), | ||||
|                                             [this](wxCommandEvent&) { sla_optimize_rotation(); }); | ||||
| 
 | ||||
|     if(printer_technology == ptFFF) item_sla_autorot = object_menu.Remove(item_sla_autorot); | ||||
|  |  | |||
|  | @ -405,9 +405,9 @@ const std::vector<std::string>& Preset::sla_print_options() | |||
|             "supports_enable", | ||||
|             "support_head_front_radius", | ||||
|             "support_head_penetration", | ||||
|             "support_head_back_radius", | ||||
|             "support_head_width", | ||||
|             "support_pillar_radius", | ||||
|             "support_pillar_widening_factor", | ||||
|             "support_base_radius", | ||||
|             "support_base_height", | ||||
|             "support_critical_angle", | ||||
|  |  | |||
|  | @ -3002,12 +3002,12 @@ void TabSLAPrint::build() | |||
| 
 | ||||
|     optgroup = page->new_optgroup(_(L("Support head"))); | ||||
|     optgroup->append_single_option_line("support_head_front_radius"); | ||||
|     optgroup->append_single_option_line("support_head_back_radius"); | ||||
|     optgroup->append_single_option_line("support_head_penetration"); | ||||
|     optgroup->append_single_option_line("support_head_width"); | ||||
| 
 | ||||
|     optgroup = page->new_optgroup(_(L("Support pillar"))); | ||||
|     optgroup->append_single_option_line("support_pillar_radius"); | ||||
|     optgroup->append_single_option_line("support_pillar_widening_factor"); | ||||
|     optgroup->append_single_option_line("support_base_radius"); | ||||
|     optgroup->append_single_option_line("support_base_height"); | ||||
|     optgroup->append_single_option_line("support_object_elevation"); | ||||
|  |  | |||
|  | @ -410,6 +410,8 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std: | |||
| 
 | ||||
|     for (auto& cat : m_opt_categories) | ||||
|         m_name += cat + "; "; | ||||
|     if (!m_name.IsEmpty()) | ||||
|         m_name.erase(m_name.Length()-2, 2); // Delete last "; "
 | ||||
| 
 | ||||
|     wxBitmap *bmp = m_bitmap_cache->find(m_name.ToStdString()); | ||||
|     if (bmp == nullptr) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv