mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into ys_hdpi
This commit is contained in:
		
						commit
						b2410e0f23
					
				
					 51 changed files with 7406 additions and 275 deletions
				
			
		|  | @ -10,6 +10,7 @@ | |||
| #include "libslic3r/Geometry.hpp" | ||||
| #include "libslic3r/Utils.hpp" | ||||
| #include "libslic3r/Technologies.hpp" | ||||
| #include "libslic3r/Tesselate.hpp" | ||||
| #include "slic3r/GUI/3DScene.hpp" | ||||
| #include "slic3r/GUI/BackgroundSlicingProcess.hpp" | ||||
| #include "slic3r/GUI/GLShader.hpp" | ||||
|  | @ -600,7 +601,8 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const | |||
| 
 | ||||
| #if ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES | ||||
|     GLfloat max_anisotropy = 0.0f; | ||||
|     ::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); | ||||
|     if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) | ||||
|         ::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); | ||||
| #endif // ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES
 | ||||
| 
 | ||||
|     std::string filename = tex_path + "_top.png"; | ||||
|  | @ -5230,6 +5232,12 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) | |||
|     if (evt.MiddleIsDown()) | ||||
|         return; | ||||
| 
 | ||||
| #if ENABLE_RETINA_GL | ||||
|     const float scale = m_retina_helper->get_scale_factor(); | ||||
|     evt.SetX(evt.GetX() * scale); | ||||
|     evt.SetY(evt.GetY() * scale); | ||||
| #endif | ||||
| 
 | ||||
|     // Performs layers editing updates, if enabled
 | ||||
|     if (is_layers_editing_enabled()) | ||||
|     { | ||||
|  | @ -6737,230 +6745,6 @@ void GLCanvas3D::_render_camera_target() const | |||
| } | ||||
| #endif // ENABLE_SHOW_CAMERA_TARGET
 | ||||
| 
 | ||||
| class TessWrapper { | ||||
| public: | ||||
| 	static Pointf3s tesselate(const ExPolygon &expoly, double z_, bool flipped_) | ||||
| 	{ | ||||
| 		z = z_; | ||||
| 		flipped = flipped_; | ||||
| 		triangles.clear(); | ||||
| 		intersection_points.clear(); | ||||
| 		std::vector<GLdouble> coords; | ||||
| 		{ | ||||
| 			size_t num_coords = expoly.contour.points.size(); | ||||
| 			for (const Polygon &poly : expoly.holes) | ||||
| 				num_coords += poly.points.size(); | ||||
| 			coords.reserve(num_coords * 3); | ||||
| 		} | ||||
| 		GLUtesselator *tess = gluNewTess(); // create a tessellator
 | ||||
| 		// register callback functions
 | ||||
| #ifndef _GLUfuncptr | ||||
| 	#ifdef _MSC_VER | ||||
| 		typedef void (__stdcall *_GLUfuncptr)(void); | ||||
| 	#else /* _MSC_VER */ | ||||
|         #ifdef GLAPIENTRYP | ||||
|             typedef void (GLAPIENTRYP _GLUfuncptr)(void); | ||||
|         #else /* GLAPIENTRYP */ | ||||
|             typedef void (*_GLUfuncptr)(void); | ||||
|         #endif | ||||
| 	#endif /* _MSC_VER */ | ||||
| #endif /* _GLUfuncptr */ | ||||
| 		gluTessCallback(tess, GLU_TESS_BEGIN,   (_GLUfuncptr)tessBeginCB); | ||||
| 		gluTessCallback(tess, GLU_TESS_END,     (_GLUfuncptr)tessEndCB); | ||||
| 		gluTessCallback(tess, GLU_TESS_ERROR,   (_GLUfuncptr)tessErrorCB); | ||||
| 		gluTessCallback(tess, GLU_TESS_VERTEX,  (_GLUfuncptr)tessVertexCB); | ||||
|         gluTessCallback(tess, GLU_TESS_COMBINE, (_GLUfuncptr)tessCombineCB); | ||||
| 		gluTessBeginPolygon(tess, 0); // with NULL data
 | ||||
| 		gluTessBeginContour(tess); | ||||
| 		for (const Point &pt : expoly.contour.points) { | ||||
| 			coords.emplace_back(unscale<double>(pt[0])); | ||||
| 			coords.emplace_back(unscale<double>(pt[1])); | ||||
| 			coords.emplace_back(0.); | ||||
| 			gluTessVertex(tess, &coords[coords.size() - 3], &coords[coords.size() - 3]); | ||||
| 		} | ||||
| 		gluTessEndContour(tess); | ||||
| 		for (const Polygon &poly : expoly.holes) { | ||||
| 			gluTessBeginContour(tess); | ||||
| 			for (const Point &pt : poly.points) { | ||||
| 				coords.emplace_back(unscale<double>(pt[0])); | ||||
| 				coords.emplace_back(unscale<double>(pt[1])); | ||||
| 				coords.emplace_back(0.); | ||||
| 				gluTessVertex(tess, &coords[coords.size() - 3], &coords[coords.size() - 3]); | ||||
| 			} | ||||
| 			gluTessEndContour(tess); | ||||
| 		} | ||||
| 		gluTessEndPolygon(tess); | ||||
| 		gluDeleteTess(tess); | ||||
| 		return std::move(triangles); | ||||
| 	} | ||||
| 
 | ||||
| private: | ||||
| 	static void tessBeginCB(GLenum which) | ||||
| 	{ | ||||
| 		assert(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP); | ||||
| 		if (!(which == GL_TRIANGLES || which == GL_TRIANGLE_FAN || which == GL_TRIANGLE_STRIP)) | ||||
| 			printf("Co je to za haluz!?\n"); | ||||
| 		primitive_type = which; | ||||
| 		num_points = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	static void tessEndCB() | ||||
| 	{ | ||||
| 		num_points = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	static void tessVertexCB(const GLvoid *data) | ||||
| 	{ | ||||
| 		if (data == nullptr) | ||||
| 			return; | ||||
| 		const GLdouble *ptr = (const GLdouble*)data; | ||||
| 		++ num_points; | ||||
| 		if (num_points == 1) { | ||||
| 			memcpy(pt0, ptr, sizeof(GLdouble) * 3); | ||||
| 		} else if (num_points == 2) { | ||||
| 			memcpy(pt1, ptr, sizeof(GLdouble) * 3); | ||||
| 		} else { | ||||
| 			bool flip = flipped; | ||||
| 			if (primitive_type == GL_TRIANGLE_STRIP && num_points == 4) { | ||||
| 				flip = !flip; | ||||
| 				num_points = 2; | ||||
| 			} | ||||
| 			triangles.emplace_back(pt0[0], pt0[1], z); | ||||
| 			if (flip) { | ||||
| 				triangles.emplace_back(ptr[0], ptr[1], z); | ||||
| 				triangles.emplace_back(pt1[0], pt1[1], z); | ||||
| 			} else { | ||||
| 				triangles.emplace_back(pt1[0], pt1[1], z); | ||||
| 				triangles.emplace_back(ptr[0], ptr[1], z); | ||||
| 			} | ||||
| 			if (primitive_type == GL_TRIANGLE_STRIP) { | ||||
| 				memcpy(pt0, pt1, sizeof(GLdouble) * 3); | ||||
| 				memcpy(pt1, ptr, sizeof(GLdouble) * 3); | ||||
| 			} else if (primitive_type == GL_TRIANGLE_FAN) { | ||||
| 				memcpy(pt1, ptr, sizeof(GLdouble) * 3); | ||||
| 			} else { | ||||
| 				assert(primitive_type == GL_TRIANGLES); | ||||
| 				assert(num_points == 3); | ||||
| 				num_points = 0; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|     static void tessCombineCB(const GLdouble newVertex[3], const GLdouble *neighborVertex[4], const GLfloat neighborWeight[4], GLdouble **outData) | ||||
|     { | ||||
|         intersection_points.emplace_back(newVertex[0], newVertex[1], newVertex[2]); | ||||
|         *outData = intersection_points.back().data(); | ||||
|     } | ||||
| 
 | ||||
| 	static void tessErrorCB(GLenum errorCode) | ||||
| 	{ | ||||
| 		const GLubyte *errorStr; | ||||
| 		errorStr = gluErrorString(errorCode); | ||||
| 		printf("Error: %s\n", (const char*)errorStr); | ||||
| 	} | ||||
| 
 | ||||
| 	static GLenum   primitive_type; | ||||
| 	static GLdouble pt0[3]; | ||||
| 	static GLdouble pt1[3]; | ||||
| 	static int      num_points; | ||||
| 	static Pointf3s triangles; | ||||
|     static std::deque<Vec3d> intersection_points; | ||||
| 	static double   z; | ||||
| 	static bool     flipped; | ||||
| }; | ||||
| 
 | ||||
| GLenum   TessWrapper::primitive_type; | ||||
| GLdouble TessWrapper::pt0[3]; | ||||
| GLdouble TessWrapper::pt1[3]; | ||||
| int      TessWrapper::num_points; | ||||
| Pointf3s TessWrapper::triangles; | ||||
| std::deque<Vec3d> TessWrapper::intersection_points; | ||||
| double   TessWrapper::z; | ||||
| bool     TessWrapper::flipped; | ||||
| 
 | ||||
| static Pointf3s triangulate_expolygons(const ExPolygons &polys, coordf_t z, bool flip) | ||||
| { | ||||
| 	Pointf3s triangles; | ||||
| #if 0 | ||||
| 	for (const ExPolygon& poly : polys) { | ||||
| 		Polygons poly_triangles; | ||||
| 		// poly.triangulate() is based on a trapezoidal decomposition implemented in an extremely expensive way by clipping the whole input contour with a polygon!
 | ||||
| 		poly.triangulate(&poly_triangles); | ||||
| 		// poly.triangulate_p2t() is based on the poly2tri library, which is not quite stable, it often ends up in a nice stack overflow!
 | ||||
| 		//        poly.triangulate_p2t(&poly_triangles);
 | ||||
| 		for (const Polygon &t : poly_triangles) | ||||
| 			if (flip) { | ||||
| 				triangles.emplace_back(to_3d(unscale(t.points[2]), z)); | ||||
| 				triangles.emplace_back(to_3d(unscale(t.points[1]), z)); | ||||
| 				triangles.emplace_back(to_3d(unscale(t.points[0]), z)); | ||||
| 			} else { | ||||
| 				triangles.emplace_back(to_3d(unscale(t.points[0]), z)); | ||||
| 				triangles.emplace_back(to_3d(unscale(t.points[1]), z)); | ||||
| 				triangles.emplace_back(to_3d(unscale(t.points[2]), z)); | ||||
| 			} | ||||
| 	} | ||||
| #else | ||||
| 
 | ||||
| //	for (const ExPolygon &poly : union_ex(simplify_polygons(to_polygons(polys), true))) {
 | ||||
|     for (const ExPolygon &poly : polys) { | ||||
| 		append(triangles, TessWrapper::tesselate(poly, z, flip)); | ||||
| 		continue; | ||||
| 
 | ||||
| 		std::list<TPPLPoly> input = expoly_to_polypartition_input(poly); | ||||
| 		std::list<TPPLPoly> output; | ||||
| 	//	int res = TPPLPartition().Triangulate_MONO(&input, &output);
 | ||||
| 		int res = TPPLPartition().Triangulate_EC(&input, &output); | ||||
| 		if (res == 1) { | ||||
| 			// Triangulation succeeded. Convert to triangles.
 | ||||
| 			size_t num_triangles = 0; | ||||
| 			for (const TPPLPoly &poly : output) | ||||
| 				if (poly.GetNumPoints() >= 3) | ||||
| 					num_triangles += (size_t)poly.GetNumPoints() - 2; | ||||
| 			triangles.reserve(triangles.size() + num_triangles * 3); | ||||
| 			for (const TPPLPoly &poly : output) { | ||||
| 				long num_points = poly.GetNumPoints(); | ||||
| 				if (num_points >= 3) { | ||||
| 					const TPPLPoint *pt0 = &poly[0]; | ||||
| 					const TPPLPoint *pt1 = nullptr; | ||||
| 					const TPPLPoint *pt2 = &poly[1]; | ||||
| 					for (long i = 2; i < num_points; ++i) { | ||||
| 						pt1 = pt2; | ||||
| 						pt2 = &poly[i]; | ||||
| 						if (flip) { | ||||
| 							triangles.emplace_back(unscale<double>(pt2->x), unscale<double>(pt2->y), z); | ||||
| 							triangles.emplace_back(unscale<double>(pt1->x), unscale<double>(pt1->y), z); | ||||
| 							triangles.emplace_back(unscale<double>(pt0->x), unscale<double>(pt0->y), z); | ||||
| 						} else { | ||||
| 							triangles.emplace_back(unscale<double>(pt0->x), unscale<double>(pt0->y), z); | ||||
| 							triangles.emplace_back(unscale<double>(pt1->x), unscale<double>(pt1->y), z); | ||||
| 							triangles.emplace_back(unscale<double>(pt2->x), unscale<double>(pt2->y), z); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			// Triangulation by polypartition failed. Use the expensive slow implementation.
 | ||||
| 			Polygons poly_triangles; | ||||
| 			// poly.triangulate() is based on a trapezoidal decomposition implemented in an extremely expensive way by clipping the whole input contour with a polygon!
 | ||||
| 			poly.triangulate(&poly_triangles); | ||||
| 			// poly.triangulate_p2t() is based on the poly2tri library, which is not quite stable, it often ends up in a nice stack overflow!
 | ||||
| 			//        poly.triangulate_p2t(&poly_triangles);
 | ||||
| 			for (const Polygon &t : poly_triangles) | ||||
| 				if (flip) { | ||||
| 					triangles.emplace_back(to_3d(unscale(t.points[2]), z)); | ||||
| 					triangles.emplace_back(to_3d(unscale(t.points[1]), z)); | ||||
| 					triangles.emplace_back(to_3d(unscale(t.points[0]), z)); | ||||
| 				} else { | ||||
| 					triangles.emplace_back(to_3d(unscale(t.points[0]), z)); | ||||
| 					triangles.emplace_back(to_3d(unscale(t.points[1]), z)); | ||||
| 					triangles.emplace_back(to_3d(unscale(t.points[2]), z)); | ||||
| 				} | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	return triangles; | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::_render_sla_slices() const | ||||
| { | ||||
|     if (!m_use_clipping_planes || wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) | ||||
|  | @ -7031,20 +6815,20 @@ void GLCanvas3D::_render_sla_slices() const | |||
|             { | ||||
|                 // calculate model bottom cap
 | ||||
|                 if (bottom_obj_triangles.empty() && (it_min_z->second.model_slices_idx < model_slices.size())) | ||||
|                     bottom_obj_triangles = triangulate_expolygons(model_slices[it_min_z->second.model_slices_idx], min_z, true); | ||||
|                     bottom_obj_triangles = triangulate_expolygons_3df(model_slices[it_min_z->second.model_slices_idx], min_z, true); | ||||
|                 // calculate support bottom cap
 | ||||
|                 if (bottom_sup_triangles.empty() && (it_min_z->second.support_slices_idx < support_slices.size())) | ||||
|                     bottom_sup_triangles = triangulate_expolygons(support_slices[it_min_z->second.support_slices_idx], min_z, true); | ||||
|                     bottom_sup_triangles = triangulate_expolygons_3df(support_slices[it_min_z->second.support_slices_idx], min_z, true); | ||||
|             } | ||||
| 
 | ||||
|             if (it_max_z != index.end()) | ||||
|             { | ||||
|                 // calculate model top cap
 | ||||
|                 if (top_obj_triangles.empty() && (it_max_z->second.model_slices_idx < model_slices.size())) | ||||
|                     top_obj_triangles = triangulate_expolygons(model_slices[it_max_z->second.model_slices_idx], max_z, false); | ||||
|                     top_obj_triangles = triangulate_expolygons_3df(model_slices[it_max_z->second.model_slices_idx], max_z, false); | ||||
|                 // calculate support top cap
 | ||||
|                 if (top_sup_triangles.empty() && (it_max_z->second.support_slices_idx < support_slices.size())) | ||||
| 					top_sup_triangles = triangulate_expolygons(support_slices[it_max_z->second.support_slices_idx], max_z, false); | ||||
| 					top_sup_triangles = triangulate_expolygons_3df(support_slices[it_max_z->second.support_slices_idx], max_z, false); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -197,7 +197,7 @@ bool GUI_App::OnInit() | |||
| 
 | ||||
| 
 | ||||
|     mainframe->Show(true); | ||||
|     return true; | ||||
|     return m_initialized = true; | ||||
| } | ||||
| 
 | ||||
| unsigned GUI_App::get_colour_approx_luma(const wxColour &colour) | ||||
|  |  | |||
|  | @ -71,6 +71,7 @@ static wxString dots("…", wxConvUTF8); | |||
| 
 | ||||
| class GUI_App : public wxApp | ||||
| { | ||||
|     bool            m_initialized { false }; | ||||
|     bool            app_conf_exists{ false }; | ||||
| 
 | ||||
|     wxColour        m_color_label_modified; | ||||
|  | @ -93,6 +94,7 @@ class GUI_App : public wxApp | |||
| 
 | ||||
| public: | ||||
|     bool            OnInit() override; | ||||
|     bool            initialized() const { return m_initialized; } | ||||
| 
 | ||||
|     GUI_App(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1348,6 +1348,8 @@ void ObjectList::split() | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     wxBusyCursor wait; | ||||
| 
 | ||||
|     auto model_object = (*m_objects)[obj_idx]; | ||||
| 
 | ||||
|     auto parent = m_objects_model->GetTopParent(item); | ||||
|  |  | |||
|  | @ -1886,6 +1886,7 @@ void Plater::priv::split_object() | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     wxBusyCursor wait; | ||||
|     ModelObjectPtrs new_objects; | ||||
|     current_model_object->split(&new_objects); | ||||
|     if (new_objects.size() == 1) | ||||
|  | @ -2824,6 +2825,7 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     wxBusyCursor wait; | ||||
|     const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower); | ||||
| 
 | ||||
|     remove(obj_idx); | ||||
|  | @ -2907,6 +2909,7 @@ void Plater::export_amf() | |||
|     const std::string path_u8 = into_u8(path); | ||||
| 
 | ||||
| 	DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); | ||||
|     wxBusyCursor wait; | ||||
| 	if (Slic3r::store_amf(path_u8.c_str(), &p->model, dialog->get_checkbox_value() ? &cfg : nullptr)) { | ||||
|         // Success
 | ||||
|         p->statusbar()->set_status_text(wxString::Format(_(L("AMF file exported to %s")), path)); | ||||
|  | @ -2937,6 +2940,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) | |||
| 
 | ||||
| 	DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); | ||||
|     const std::string path_u8 = into_u8(path); | ||||
|     wxBusyCursor wait; | ||||
|     if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { | ||||
|         // Success
 | ||||
|         p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path)); | ||||
|  |  | |||
|  | @ -414,6 +414,7 @@ const std::vector<std::string>& Preset::sla_print_options() | |||
|             "support_head_width", | ||||
|             "support_pillar_diameter", | ||||
|             "support_pillar_connection_mode", | ||||
|             "support_buildplate_only", | ||||
|             "support_pillar_widening_factor", | ||||
|             "support_base_diameter", | ||||
|             "support_base_height", | ||||
|  |  | |||
|  | @ -3199,6 +3199,7 @@ void TabSLAPrint::build() | |||
|     optgroup = page->new_optgroup(_(L("Support pillar"))); | ||||
|     optgroup->append_single_option_line("support_pillar_diameter"); | ||||
|     optgroup->append_single_option_line("support_pillar_connection_mode"); | ||||
|     optgroup->append_single_option_line("support_buildplate_only"); | ||||
|     optgroup->append_single_option_line("support_pillar_widening_factor"); | ||||
|     optgroup->append_single_option_line("support_base_diameter"); | ||||
|     optgroup->append_single_option_line("support_base_height"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka