mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
		
						commit
						022e325a60
					
				
					 21 changed files with 546 additions and 75 deletions
				
			
		
							
								
								
									
										37
									
								
								resources/icons/copy.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								resources/icons/copy.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
| <svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||
| 	 viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve"> | ||||
| <g id="copy"> | ||||
| 	<g> | ||||
| 		<path fill="#ED6B21" d="M115.76,51.2l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04 | ||||
| 			c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.17,118.23,53.67,115.76,51.2z M111.42,54.04h-6.57 | ||||
| 			v-6.57L111.42,54.04z M115.01,112.47c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.42 | ||||
| 			c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54 | ||||
| 			V112.47z"/> | ||||
| 		<path fill="#ED6B21" d="M53.97,59.13h35.72c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H53.97c-1.4,0-2.54,1.14-2.54,2.54 | ||||
| 			S52.56,59.13,53.97,59.13z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,69.29H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,69.29,104.93,69.29z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,84.53H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,84.53,104.93,84.53z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,99.77H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,99.77,104.93,99.77z"/> | ||||
| 	</g> | ||||
| 	<g> | ||||
| 		<path fill="#FFFFFF" d="M85.27,20.71l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04 | ||||
| 			c0,4.2,3.42,7.62,7.62,7.62h17.78c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H15.94c-1.4,0-2.54-1.14-2.54-2.54V15.94 | ||||
| 			c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46V26.1c0,1.4,1.14,2.54,2.54,2.54h12.45c0.16,0.49,0.25,0.93,0.25,1.27 | ||||
| 			v3.81c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54v-3.81C89.61,27.14,87.75,23.19,85.27,20.71z M74.37,16.99l6.57,6.57 | ||||
| 			h-6.57V16.99z"/> | ||||
| 		<path fill="#FFFFFF" d="M59.21,23.56H23.48c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h35.72c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S60.61,23.56,59.21,23.56z"/> | ||||
| 		<path fill="#FFFFFF" d="M28.73,38.8h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S30.13,38.8,28.73,38.8z"/> | ||||
| 		<path fill="#FFFFFF" d="M28.73,54.04h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S30.13,54.04,28.73,54.04z"/> | ||||
| 		<path fill="#FFFFFF" d="M28.73,69.29h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S30.13,69.29,28.73,69.29z"/> | ||||
| 	</g> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.6 KiB | 
							
								
								
									
										37
									
								
								resources/icons/copy_menu.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								resources/icons/copy_menu.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
| <svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||
| 	 viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve"> | ||||
| <g id="copy"> | ||||
| 	<g> | ||||
| 		<path fill="#ED6B21" d="M115.76,51.2l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04 | ||||
| 			c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.17,118.23,53.67,115.76,51.2z M111.42,54.04h-6.57 | ||||
| 			v-6.57L111.42,54.04z M115.01,112.47c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.42 | ||||
| 			c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54 | ||||
| 			V112.47z"/> | ||||
| 		<path fill="#ED6B21" d="M53.97,59.13h35.72c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H53.97c-1.4,0-2.54,1.14-2.54,2.54 | ||||
| 			S52.56,59.13,53.97,59.13z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,69.29H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,69.29,104.93,69.29z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,84.53H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,84.53,104.93,84.53z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,99.77H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,99.77,104.93,99.77z"/> | ||||
| 	</g> | ||||
| 	<g> | ||||
| 		<path fill="#808080" d="M85.27,20.71l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04 | ||||
| 			c0,4.2,3.42,7.62,7.62,7.62h17.78c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H15.94c-1.4,0-2.54-1.14-2.54-2.54V15.94 | ||||
| 			c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46V26.1c0,1.4,1.14,2.54,2.54,2.54h12.45c0.16,0.49,0.25,0.93,0.25,1.27 | ||||
| 			v3.81c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54v-3.81C89.61,27.14,87.75,23.19,85.27,20.71z M74.37,16.99l6.57,6.57 | ||||
| 			h-6.57V16.99z"/> | ||||
| 		<path fill="#808080" d="M59.21,23.56H23.48c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h35.72c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S60.61,23.56,59.21,23.56z"/> | ||||
| 		<path fill="#808080" d="M28.73,38.8h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S30.13,38.8,28.73,38.8z"/> | ||||
| 		<path fill="#808080" d="M28.73,54.04h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S30.13,54.04,28.73,54.04z"/> | ||||
| 		<path fill="#808080" d="M28.73,69.29h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S30.13,69.29,28.73,69.29z"/> | ||||
| 	</g> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.6 KiB | 
							
								
								
									
										31
									
								
								resources/icons/delete_all_menu.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								resources/icons/delete_all_menu.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
| <svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||
| 	 viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve"> | ||||
| <g id="DELETE_ALL_1_"> | ||||
| 	<path fill="#808080" d="M103.52,43.87l-13.31,69.97H37.79L24.48,43.87H103.52 M108.77,37.87H19.23c-1.1,0-1.83,0.88-1.63,1.96 | ||||
| 		l14.84,78.04c0.21,1.08,1.27,1.96,2.37,1.96h58.36c1.1,0,2.17-0.88,2.37-1.96l14.84-78.04C110.6,38.75,109.87,37.87,108.77,37.87 | ||||
| 		L108.77,37.87z"/> | ||||
| 	<g> | ||||
| 		<path fill="#ED6B21" d="M89.38,22.97c-1.1,0-2-0.9-2-2v-10.9c0-1.1-0.9-2-2-2H42.62c-1.1,0-2,0.9-2,2v10.9c0,1.1-0.9,2-2,2H19.23 | ||||
| 			c-1.1,0-2,0.9-2,2v3.45c0,1.1,0.9,2,2,2h89.54c1.1,0,2-0.9,2-2v-3.45c0-1.1-0.9-2-2-2H89.38z M79.59,20.97c0,1.1-0.9,2-2,2H50.41 | ||||
| 			c-1.1,0-2-0.9-2-2v-3.45c0-1.1,0.9-2,2-2h27.18c1.1,0,2,0.9,2,2V20.97z"/> | ||||
| 	</g> | ||||
| 	<g> | ||||
| 		<path fill="#808080" d="M93.17,73.5H34.83c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h58.34c0.83,0,1.5,0.67,1.5,1.5 | ||||
| 			S94,73.5,93.17,73.5z"/> | ||||
| 	</g> | ||||
| 	<g> | ||||
| 		<path fill="#808080" d="M90.14,89.45H37.96c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h52.18c0.83,0,1.5,0.67,1.5,1.5 | ||||
| 			S90.97,89.45,90.14,89.45z"/> | ||||
| 	</g> | ||||
| 	<g> | ||||
| 		<path fill="#808080" d="M87.1,105.4H40.9c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h46.2c0.83,0,1.5,0.67,1.5,1.5 | ||||
| 			S87.93,105.4,87.1,105.4z"/> | ||||
| 	</g> | ||||
| 	<g> | ||||
| 		<path fill="#808080" d="M96.2,57.56H31.8c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h64.4c0.83,0,1.5,0.67,1.5,1.5 | ||||
| 			S97.03,57.56,96.2,57.56z"/> | ||||
| 	</g> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										27
									
								
								resources/icons/paste.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								resources/icons/paste.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
| <svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||
| 	 viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve"> | ||||
| <g id="paste"> | ||||
| 	<path fill="#FFFFFF" d="M33.73,107.03H15.94c-1.4,0-2.54-1.14-2.54-2.54V23.52c0-1.4,1.14-2.54,2.54-2.54h7.62v5.08 | ||||
| 		c0,1.4,1.14,2.54,2.54,2.54h45.72c1.4,0,2.54-1.14,2.54-2.54v-5.08h7.62c1.4,0,2.54,1.14,2.54,2.54v10.16 | ||||
| 		c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54V23.52c0-4.2-3.42-7.62-7.62-7.62h-7.62v-5.08c0-1.4-1.14-2.54-2.54-2.54 | ||||
| 		H26.11c-1.4,0-2.54,1.14-2.54,2.54v5.08h-7.62c-4.2,0-7.62,3.42-7.62,7.62v80.97c0,4.2,3.42,7.62,7.62,7.62h17.78 | ||||
| 		c1.4,0,2.54-1.14,2.54-2.54C36.27,108.16,35.13,107.03,33.73,107.03z M28.65,13.36h40.64v10.16H28.65V13.36z"/> | ||||
| 	<g> | ||||
| 		<path fill="#ED6B21" d="M53.97,59.08h35.72c1.4,0,2.54-1.14,2.54-2.54c0-1.4-1.14-2.54-2.54-2.54H53.97 | ||||
| 			c-1.4,0-2.54,1.14-2.54,2.54C51.43,57.94,52.56,59.08,53.97,59.08z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,69.24H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96 | ||||
| 			c1.4,0,2.54-1.14,2.54-2.54C107.47,70.38,106.33,69.24,104.93,69.24z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,99.72H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,99.72,104.93,99.72z"/> | ||||
| 		<path fill="#ED6B21" d="M115.75,51.15l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04 | ||||
| 			c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.12,118.23,53.62,115.75,51.15z M104.85,47.43 | ||||
| 			l6.57,6.57h-6.57V47.43z M115.01,112.42c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.38 | ||||
| 			c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54 | ||||
| 			V112.42z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,84.48H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96 | ||||
| 			c1.4,0,2.54-1.14,2.54-2.54C107.47,85.62,106.33,84.48,104.93,84.48z"/> | ||||
| 	</g> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										27
									
								
								resources/icons/paste_menu.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								resources/icons/paste_menu.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
| <svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||
| 	 viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve"> | ||||
| <g id="paste"> | ||||
| 	<path fill="#808080" d="M33.73,107.03H15.94c-1.4,0-2.54-1.14-2.54-2.54V23.52c0-1.4,1.14-2.54,2.54-2.54h7.62v5.08 | ||||
| 		c0,1.4,1.14,2.54,2.54,2.54h45.72c1.4,0,2.54-1.14,2.54-2.54v-5.08h7.62c1.4,0,2.54,1.14,2.54,2.54v10.16 | ||||
| 		c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54V23.52c0-4.2-3.42-7.62-7.62-7.62h-7.62v-5.08c0-1.4-1.14-2.54-2.54-2.54 | ||||
| 		H26.11c-1.4,0-2.54,1.14-2.54,2.54v5.08h-7.62c-4.2,0-7.62,3.42-7.62,7.62v80.97c0,4.2,3.42,7.62,7.62,7.62h17.78 | ||||
| 		c1.4,0,2.54-1.14,2.54-2.54C36.27,108.16,35.13,107.03,33.73,107.03z M28.65,13.36h40.64v10.16H28.65V13.36z"/> | ||||
| 	<g> | ||||
| 		<path fill="#ED6B21" d="M53.97,59.08h35.72c1.4,0,2.54-1.14,2.54-2.54c0-1.4-1.14-2.54-2.54-2.54H53.97 | ||||
| 			c-1.4,0-2.54,1.14-2.54,2.54C51.43,57.94,52.56,59.08,53.97,59.08z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,69.24H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96 | ||||
| 			c1.4,0,2.54-1.14,2.54-2.54C107.47,70.38,106.33,69.24,104.93,69.24z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,99.72H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54 | ||||
| 			S106.33,99.72,104.93,99.72z"/> | ||||
| 		<path fill="#ED6B21" d="M115.75,51.15l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04 | ||||
| 			c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.12,118.23,53.62,115.75,51.15z M104.85,47.43 | ||||
| 			l6.57,6.57h-6.57V47.43z M115.01,112.42c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.38 | ||||
| 			c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54 | ||||
| 			V112.42z"/> | ||||
| 		<path fill="#ED6B21" d="M104.93,84.48H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96 | ||||
| 			c1.4,0,2.54-1.14,2.54-2.54C107.47,85.62,106.33,84.48,104.93,84.48z"/> | ||||
| 	</g> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										44
									
								
								resources/icons/remove_menu.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								resources/icons/remove_menu.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
| <svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||
| 	 viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve"> | ||||
| <path fill="#808080" d="M38.11,44.25H25.75c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72H38.1c0.95,0,1.72-0.77,1.72-1.72 | ||||
| 	C39.83,45.02,39.06,44.25,38.11,44.25z M45.89,45.97c0,0.95,0.77,1.72,1.72,1.72h12.35c0.95,0,1.72-0.77,1.72-1.72 | ||||
| 	s-0.77-1.72-1.72-1.72H47.61C46.66,44.25,45.89,45.02,45.89,45.97z M68.11,43.6c-0.33,0.28-0.52,0.65-0.59,1.04 | ||||
| 	c-0.59,0.27-1,0.87-1,1.56v5.6c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72v-5.34c0.12-0.06,0.24-0.13,0.35-0.22 | ||||
| 	c0.13-0.11,0.25-0.23,0.36-0.34l8.27-8.77c0.65-0.69,0.62-1.78-0.07-2.43s-1.78-0.62-2.43,0.07l-8.27,8.78 | ||||
| 	C68.16,43.56,68.14,43.58,68.11,43.6z M68.25,76.84c-0.95,0-1.72,0.77-1.72,1.72V89.1c0,0.95,0.77,1.72,1.72,1.72 | ||||
| 	c0.95,0,1.72-0.77,1.72-1.72V78.56C69.97,77.61,69.2,76.84,68.25,76.84z M69.97,59.91c0-0.95-0.77-1.72-1.72-1.72 | ||||
| 	c-0.95,0-1.72,0.77-1.72,1.72v10.54c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72V59.91z M88.92,56.35 | ||||
| 	c-0.95,0-1.72,0.77-1.72,1.72v3.4c0,0.34-0.02,0.63-0.04,0.85c-0.51,0.55-0.62,1.38-0.22,2.06c0.32,0.54,0.89,0.84,1.48,0.84 | ||||
| 	c0.3,0,0.6-0.08,0.88-0.24l0.25-0.15c0.67-0.4,1.09-1.1,1.09-3.35v-3.4C90.64,57.12,89.87,56.35,88.92,56.35z M41.81,26.17h11.3 | ||||
| 	c0.95,0,1.72-0.77,1.72-1.72s-0.77-1.72-1.72-1.72h-11.3c-0.95,0-1.72,0.77-1.72,1.72S40.86,26.17,41.81,26.17z M87.2,22.73h-5.39 | ||||
| 	c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72h2.75l-1.58,1.68c-0.65,0.69-0.62,1.78,0.07,2.43c0.33,0.31,0.76,0.47,1.18,0.47 | ||||
| 	c0.46,0,0.91-0.18,1.25-0.54l1.72-1.82v0.99c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72v-3.21 | ||||
| 	C90.64,24.27,89.09,22.73,87.2,22.73z M61.81,26.17h11.3c0.95,0,1.72-0.77,1.72-1.72s-0.77-1.72-1.72-1.72h-11.3 | ||||
| 	c-0.95,0-1.72,0.77-1.72,1.72S60.86,26.17,61.81,26.17z M9.71,67.54c0.95,0,1.72-0.77,1.72-1.72v-11.3c0-0.95-0.77-1.72-1.72-1.72 | ||||
| 	s-1.72,0.77-1.72,1.72v11.3C7.99,66.77,8.76,67.54,9.71,67.54z M24.65,33.86c0.42,0,0.84-0.15,1.17-0.46l7.04-6.52 | ||||
| 	c0.14-0.13,0.46-0.34,0.9-0.51c0.89-0.34,1.34-1.33,1-2.22s-1.33-1.34-2.22-1c-0.8,0.3-1.52,0.73-2.03,1.2l-7.04,6.52 | ||||
| 	c-0.7,0.65-0.74,1.74-0.09,2.43C23.73,33.68,24.19,33.86,24.65,33.86z M70.35,99.28l-0.37,0.36v-2.43c0-0.95-0.77-1.72-1.72-1.72 | ||||
| 	c-0.95,0-1.72,0.77-1.72,1.72v4.72H61.3c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72h5.23c1.4,0,3.15-0.7,4.16-1.66l2.03-1.94 | ||||
| 	c0.69-0.66,0.71-1.75,0.06-2.43C72.13,98.65,71.03,98.63,70.35,99.28z M52.6,101.93H41.3c-0.95,0-1.72,0.77-1.72,1.72 | ||||
| 	s0.77,1.72,1.72,1.72h11.3c0.95,0,1.72-0.77,1.72-1.72S53.55,101.93,52.6,101.93z M88.92,36.35c-0.95,0-1.72,0.77-1.72,1.72v11.3 | ||||
| 	c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72v-11.3C90.64,37.12,89.87,36.35,88.92,36.35z M32.61,101.93H21.3 | ||||
| 	c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72h11.3c0.95,0,1.72-0.77,1.72-1.72S33.56,101.93,32.61,101.93z M9.71,87.54 | ||||
| 	c0.95,0,1.72-0.77,1.72-1.72v-11.3c0-0.95-0.77-1.72-1.72-1.72s-1.72,0.77-1.72,1.72v11.3C7.99,86.77,8.76,87.54,9.71,87.54z | ||||
| 	 M12.61,101.93h-1.18v-7.42c0-0.95-0.77-1.72-1.72-1.72s-1.72,0.77-1.72,1.72v7.42c0,1.9,1.54,3.44,3.44,3.44h1.18 | ||||
| 	c0.95,0,1.72-0.77,1.72-1.72S13.56,101.93,12.61,101.93z M19.53,36.88c-0.65-0.7-1.74-0.74-2.43-0.09l-7.3,6.76 | ||||
| 	c-0.55,0.51-0.93,1.15-1.16,1.6C8.22,46,8.56,47.03,9.41,47.46c0.25,0.12,0.51,0.18,0.77,0.18h0.01c0.14,0.04,0.29,0.07,0.45,0.07 | ||||
| 	h5.6c0.95,0,1.72-0.77,1.72-1.72s-0.77-1.72-1.72-1.72h-2.13l5.33-4.94C20.14,38.66,20.18,37.57,19.53,36.88z M80.7,89.4l-4.05,3.86 | ||||
| 	c-0.69,0.66-0.71,1.75-0.06,2.43c0.34,0.35,0.79,0.53,1.25,0.53c0.43,0,0.86-0.16,1.19-0.48l4.05-3.86 | ||||
| 	c0.69-0.66,0.71-1.75,0.06-2.43C82.48,88.77,81.39,88.75,80.7,89.4z"/> | ||||
| <g> | ||||
| 	<path fill="#ED6B21" d="M98.82,101.06c-11.63,0-21.09-9.46-21.09-21.09s9.46-21.09,21.09-21.09s21.09,9.46,21.09,21.09 | ||||
| 		S110.45,101.06,98.82,101.06z M98.82,62.32c-9.73,0-17.65,7.92-17.65,17.65s7.92,17.65,17.65,17.65s17.65-7.92,17.65-17.65 | ||||
| 		S108.55,62.32,98.82,62.32z"/> | ||||
| </g> | ||||
| <g> | ||||
| 	<path fill="#ED6B21" d="M110.44,81.84c0,1.1-0.9,2-2,2H89.2c-1.1,0-2-0.9-2-2v-3.75c0-1.1,0.9-2,2-2h19.25c1.1,0,2,0.9,2,2 | ||||
| 		L110.44,81.84L110.44,81.84z"/> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.2 KiB | 
|  | @ -721,32 +721,37 @@ int GLVolumeCollection::load_wipe_tower_preview( | |||
|     return int(this->volumes.size() - 1); | ||||
| } | ||||
| 
 | ||||
| typedef std::pair<GLVolume*, double> GLVolumeWithZ; | ||||
| typedef std::vector<GLVolumeWithZ> GLVolumesWithZList; | ||||
| static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func) | ||||
| GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func) | ||||
| { | ||||
|     GLVolumesWithZList list; | ||||
|     GLVolumeWithIdAndZList list; | ||||
|     list.reserve(volumes.size()); | ||||
| 
 | ||||
|     for (GLVolume* volume : volumes) | ||||
|     for (unsigned int i = 0; i < (unsigned int)volumes.size(); ++i) | ||||
|     { | ||||
|         GLVolume* volume = volumes[i]; | ||||
|         bool is_transparent = (volume->render_color[3] < 1.0f); | ||||
|         if ((((type == GLVolumeCollection::Opaque) && !is_transparent) || | ||||
|              ((type == GLVolumeCollection::Transparent) && is_transparent) || | ||||
|              (type == GLVolumeCollection::All)) && | ||||
|             (! filter_func || filter_func(*volume))) | ||||
|             list.emplace_back(std::make_pair(volume, 0.0)); | ||||
|             list.emplace_back(std::make_pair(volume, std::make_pair(i, 0.0))); | ||||
|     } | ||||
| 
 | ||||
|     if ((type == GLVolumeCollection::Transparent) && (list.size() > 1)) | ||||
|     { | ||||
|         for (GLVolumeWithZ& volume : list) | ||||
|         for (GLVolumeWithIdAndZ& volume : list) | ||||
|         { | ||||
|             volume.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2); | ||||
|             volume.second.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2); | ||||
|         } | ||||
| 
 | ||||
|         std::sort(list.begin(), list.end(), | ||||
|             [](const GLVolumeWithZ& v1, const GLVolumeWithZ& v2) -> bool { return v1.second < v2.second; } | ||||
|             [](const GLVolumeWithIdAndZ& v1, const GLVolumeWithIdAndZ& v2) -> bool { return v1.second.second < v2.second.second; } | ||||
|         ); | ||||
|     } | ||||
|     else if ((type == GLVolumeCollection::Opaque) && (list.size() > 1)) | ||||
|     { | ||||
|         std::sort(list.begin(), list.end(), | ||||
|             [](const GLVolumeWithIdAndZ& v1, const GLVolumeWithIdAndZ& v2) -> bool { return v1.first->selected && !v2.first->selected; } | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|  | @ -788,9 +793,8 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool | |||
|     if (clipping_plane_id != -1) | ||||
|         glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)clipping_plane)); | ||||
| 
 | ||||
|     GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); | ||||
| 
 | ||||
|     for (GLVolumeWithZ& volume : to_render) { | ||||
|     GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); | ||||
|     for (GLVolumeWithIdAndZ& volume : to_render) { | ||||
|         volume.first->set_render_color(); | ||||
|         volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id); | ||||
|     } | ||||
|  | @ -819,8 +823,8 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, | |||
|     glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); | ||||
|     glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); | ||||
|   | ||||
|     GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); | ||||
|     for (GLVolumeWithZ& volume : to_render) | ||||
|     GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func); | ||||
|     for (GLVolumeWithIdAndZ& volume : to_render) | ||||
|     { | ||||
|         volume.first->set_render_color(); | ||||
|         volume.first->render_legacy(); | ||||
|  |  | |||
|  | @ -412,6 +412,8 @@ public: | |||
| }; | ||||
| 
 | ||||
| typedef std::vector<GLVolume*> GLVolumePtrs; | ||||
| typedef std::pair<GLVolume*, std::pair<unsigned int, double>> GLVolumeWithIdAndZ; | ||||
| typedef std::vector<GLVolumeWithIdAndZ> GLVolumeWithIdAndZList; | ||||
| 
 | ||||
| class GLVolumeCollection | ||||
| { | ||||
|  | @ -509,6 +511,8 @@ private: | |||
|     GLVolumeCollection& operator=(const GLVolumeCollection &); | ||||
| }; | ||||
| 
 | ||||
| GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = nullptr); | ||||
| 
 | ||||
| class GLModel | ||||
| { | ||||
| protected: | ||||
|  |  | |||
|  | @ -3232,12 +3232,37 @@ bool GLCanvas3D::_init_toolbar() | |||
|     if (!m_toolbar.add_separator()) | ||||
|         return false; | ||||
| 
 | ||||
|     item.name = "copy"; | ||||
| #if ENABLE_SVG_ICONS | ||||
|     item.icon_filename = "copy.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Copy") + " [" + GUI::shortkey_ctrl_prefix() + "C]"; | ||||
|     item.sprite_id = 4; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); }; | ||||
|     item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_copy(); }; | ||||
|     if (!m_toolbar.add_item(item)) | ||||
|         return false; | ||||
| 
 | ||||
|     item.name = "paste"; | ||||
| #if ENABLE_SVG_ICONS | ||||
|     item.icon_filename = "paste.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Paste") + " [" + GUI::shortkey_ctrl_prefix() + "V]"; | ||||
|     item.sprite_id = 5; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); }; | ||||
|     item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_paste(); }; | ||||
|     if (!m_toolbar.add_item(item)) | ||||
|         return false; | ||||
| 
 | ||||
|     if (!m_toolbar.add_separator()) | ||||
|         return false; | ||||
| 
 | ||||
|     item.name = "more"; | ||||
| #if ENABLE_SVG_ICONS | ||||
|     item.icon_filename = "instance_add.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Add instance [+]"); | ||||
|     item.sprite_id = 4; | ||||
|     item.sprite_id = 6; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); }; | ||||
|     item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; | ||||
|     item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); }; | ||||
|  | @ -3249,7 +3274,7 @@ bool GLCanvas3D::_init_toolbar() | |||
|     item.icon_filename = "instance_remove.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Remove instance [-]"); | ||||
|     item.sprite_id = 5; | ||||
|     item.sprite_id = 7; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); }; | ||||
|     item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; | ||||
|     item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); }; | ||||
|  | @ -3264,7 +3289,7 @@ bool GLCanvas3D::_init_toolbar() | |||
|     item.icon_filename = "split_objects.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Split to objects"); | ||||
|     item.sprite_id = 6; | ||||
|     item.sprite_id = 8; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); }; | ||||
|     item.visibility_callback = GLToolbarItem::Default_Visibility_Callback; | ||||
|     item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); }; | ||||
|  | @ -3276,7 +3301,7 @@ bool GLCanvas3D::_init_toolbar() | |||
|     item.icon_filename = "split_parts.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Split to parts"); | ||||
|     item.sprite_id = 7; | ||||
|     item.sprite_id = 9; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); }; | ||||
|     item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; }; | ||||
|     item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); }; | ||||
|  | @ -3291,7 +3316,7 @@ bool GLCanvas3D::_init_toolbar() | |||
|     item.icon_filename = "layers.svg"; | ||||
| #endif // ENABLE_SVG_ICONS
 | ||||
|     item.tooltip = GUI::L_str("Layers editing"); | ||||
|     item.sprite_id = 8; | ||||
|     item.sprite_id = 10; | ||||
|     item.is_toggable = true; | ||||
|     item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; | ||||
|     item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; }; | ||||
|  | @ -3501,7 +3526,7 @@ void GLCanvas3D::_picking_pass() const | |||
|             ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data()); | ||||
|             ::glEnable(GL_CLIP_PLANE0); | ||||
|         } | ||||
|         _render_volumes(true); | ||||
|         _render_volumes_for_picking(); | ||||
|         if (! m_use_VBOs) | ||||
|             ::glDisable(GL_CLIP_PLANE0); | ||||
| 
 | ||||
|  | @ -3702,13 +3727,10 @@ void GLCanvas3D::_render_legend_texture() const | |||
|     m_legend_texture.render(*this); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::_render_volumes(bool fake_colors) const | ||||
| void GLCanvas3D::_render_volumes_for_picking() const | ||||
| { | ||||
|     static const GLfloat INV_255 = 1.0f / 255.0f; | ||||
| 
 | ||||
|     if (!fake_colors) | ||||
|         glsafe(::glEnable(GL_LIGHTING)); | ||||
| 
 | ||||
|     // do not cull backfaces to show broken geometry, if any
 | ||||
|     glsafe(::glDisable(GL_CULL_FACE)); | ||||
| 
 | ||||
|  | @ -3718,27 +3740,31 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const | |||
|     glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); | ||||
|     glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); | ||||
| 
 | ||||
|     unsigned int volume_id = 0; | ||||
|     for (GLVolume* vol : m_volumes.volumes) | ||||
|     { | ||||
|         if (fake_colors) | ||||
|     const Transform3d& view_matrix = m_camera.get_view_matrix(); | ||||
|     GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Opaque, view_matrix); | ||||
|     for (const GLVolumeWithIdAndZ& volume : to_render) | ||||
|     { | ||||
|         // Object picking mode. Render the object with a color encoding the object index.
 | ||||
|             unsigned int r = (volume_id & 0x000000FF) >> 0; | ||||
|             unsigned int g = (volume_id & 0x0000FF00) >> 8; | ||||
|             unsigned int b = (volume_id & 0x00FF0000) >> 16; | ||||
|         unsigned int r = (volume.second.first & 0x000000FF) >> 0; | ||||
|         unsigned int g = (volume.second.first & 0x0000FF00) >> 8; | ||||
|         unsigned int b = (volume.second.first & 0x00FF0000) >> 16; | ||||
|         glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255)); | ||||
| 
 | ||||
|         if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) | ||||
|             volume.first->render(); | ||||
|     } | ||||
|         else | ||||
| 
 | ||||
|     to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Transparent, view_matrix); | ||||
|     for (const GLVolumeWithIdAndZ& volume : to_render) | ||||
|     { | ||||
|             vol->set_render_color(); | ||||
|             glsafe(::glColor4fv(vol->render_color)); | ||||
|         } | ||||
|         // Object picking mode. Render the object with a color encoding the object index.
 | ||||
|         unsigned int r = (volume.second.first & 0x000000FF) >> 0; | ||||
|         unsigned int g = (volume.second.first & 0x0000FF00) >> 8; | ||||
|         unsigned int b = (volume.second.first & 0x00FF0000) >> 16; | ||||
|         glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255)); | ||||
| 
 | ||||
|         if ((!fake_colors || !vol->disabled) && (vol->composite_id.volume_id >= 0 || m_render_sla_auxiliaries)) | ||||
|             vol->render(); | ||||
| 
 | ||||
|         ++volume_id; | ||||
|         if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) | ||||
|             volume.first->render(); | ||||
|     } | ||||
| 
 | ||||
|     glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); | ||||
|  | @ -3746,9 +3772,6 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const | |||
|     glsafe(::glDisable(GL_BLEND)); | ||||
| 
 | ||||
|     glsafe(::glEnable(GL_CULL_FACE)); | ||||
| 
 | ||||
|     if (!fake_colors) | ||||
|         glsafe(::glDisable(GL_LIGHTING)); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::_render_current_gizmo() const | ||||
|  | @ -4026,15 +4049,9 @@ void GLCanvas3D::_update_volumes_hover_state() const | |||
|         return; | ||||
| 
 | ||||
|     GLVolume* volume = m_volumes.volumes[m_hover_volume_id]; | ||||
| 
 | ||||
|     switch (m_selection.get_mode()) | ||||
|     { | ||||
|     case Selection::Volume: | ||||
|     { | ||||
|     if (volume->is_modifier) | ||||
|         volume->hover = true; | ||||
|         break; | ||||
|     } | ||||
|     case Selection::Instance: | ||||
|     else | ||||
|     { | ||||
|         int object_idx = volume->object_idx(); | ||||
|         int instance_idx = volume->instance_idx(); | ||||
|  | @ -4044,9 +4061,6 @@ void GLCanvas3D::_update_volumes_hover_state() const | |||
|             if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) | ||||
|                 v->hover = true; | ||||
|         } | ||||
| 
 | ||||
|         break; | ||||
|     } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -609,7 +609,7 @@ private: | |||
| #endif // ENABLE_RENDER_SELECTION_CENTER
 | ||||
|     void _render_warning_texture() const; | ||||
|     void _render_legend_texture() const; | ||||
|     void _render_volumes(bool fake_colors) const; | ||||
|     void _render_volumes_for_picking() const; | ||||
|     void _render_current_gizmo() const; | ||||
|     void _render_gizmos_overlay() const; | ||||
|     void _render_toolbar() const; | ||||
|  |  | |||
|  | @ -21,6 +21,8 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent); | |||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent); | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent); | |||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent); | ||||
|  |  | |||
|  | @ -439,6 +439,66 @@ void ObjectList::selection_changed() | |||
|     part_selection_changed(); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes) | ||||
| { | ||||
|     if ((obj_idx < 0) || ((int)m_objects->size() <= obj_idx)) | ||||
|         return; | ||||
| 
 | ||||
|     if (volumes.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     ModelObject& model_object = *(*m_objects)[obj_idx]; | ||||
|     const auto object_item = m_objects_model->GetItemById(obj_idx); | ||||
| 
 | ||||
|     wxDataViewItemArray items; | ||||
| 
 | ||||
|     for (const ModelVolume* volume : volumes) | ||||
|     { | ||||
|         auto vol_item = m_objects_model->AddVolumeChild(object_item, volume->name, volume->type(), | ||||
|             volume->config.has("extruder") ? volume->config.option<ConfigOptionInt>("extruder")->value : 0); | ||||
|         auto opt_keys = volume->config.keys(); | ||||
|         if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder"))) | ||||
|             select_item(m_objects_model->AddSettingsChild(vol_item)); | ||||
| 
 | ||||
|         items.Add(vol_item); | ||||
|     } | ||||
| 
 | ||||
|     m_parts_changed = true; | ||||
|     parts_changed(obj_idx); | ||||
| 
 | ||||
|     if (items.size() > 1) | ||||
|     { | ||||
|         m_selection_mode = smVolume; | ||||
|         m_last_selected_item = wxDataViewItem(0); | ||||
|     } | ||||
| 
 | ||||
|     select_items(items); | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs) | ||||
| { | ||||
|     if (object_idxs.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     wxDataViewItemArray items; | ||||
|     for (const size_t object : object_idxs) | ||||
|     { | ||||
|         add_object_to_list(object); | ||||
|         m_parts_changed = true; | ||||
|         parts_changed(object); | ||||
| 
 | ||||
|         items.Add(m_objects_model->GetItemById(object)); | ||||
|     } | ||||
| 
 | ||||
|     select_items(items); | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
| } | ||||
| 
 | ||||
| void ObjectList::OnChar(wxKeyEvent& event) | ||||
| { | ||||
|     if (event.GetKeyCode() == WXK_BACK){ | ||||
|  | @ -2135,6 +2195,7 @@ void ObjectList::update_selections_on_canvas() | |||
|         add_to_selection(item, selection, instance_idx, false); | ||||
| 
 | ||||
|     wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state(); | ||||
|     wxGetApp().plater()->canvas3D()->render(); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::select_item(const wxDataViewItem& item) | ||||
|  |  | |||
|  | @ -31,6 +31,8 @@ typedef std::map<std::string, std::vector<std::string>> FreqSettingsBundle; | |||
| //				  category ->		vector 			 ( option	;  label )
 | ||||
| typedef std::map< std::string, std::vector< std::pair<std::string, std::string> > > settings_menu_hierarchy; | ||||
| 
 | ||||
| typedef std::vector<ModelVolume*> ModelVolumePtrs; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 
 | ||||
| wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent); | ||||
|  | @ -285,6 +287,10 @@ public: | |||
|     void rename_item(); | ||||
|     void fix_through_netfabb() const; | ||||
|     void update_item_error_icon(const int obj_idx, int vol_idx) const ; | ||||
| 
 | ||||
|     void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes); | ||||
|     void paste_objects_into_list(const std::vector<size_t>& object_idxs); | ||||
| 
 | ||||
| private: | ||||
|     void OnChar(wxKeyEvent& event); | ||||
|     void OnContextMenu(wxDataViewEvent &event); | ||||
|  |  | |||
|  | @ -375,13 +375,22 @@ void MainFrame::init_menubar() | |||
|             [this](wxCommandEvent&) { m_plater->select_all(); }, ""); | ||||
|         editMenu->AppendSeparator(); | ||||
|         wxMenuItem* item_delete_sel = append_menu_item(editMenu, wxID_ANY, _(L("&Delete selected")) + sep + hotkey_delete, _(L("Deletes the current selection")), | ||||
|             [this](wxCommandEvent&) { m_plater->remove_selected(); }, ""); | ||||
|             [this](wxCommandEvent&) { m_plater->remove_selected(); }, "remove_menu"); | ||||
|         wxMenuItem* item_delete_all = append_menu_item(editMenu, wxID_ANY, _(L("Delete &all")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + hotkey_delete, _(L("Deletes all objects")), | ||||
|             [this](wxCommandEvent&) { m_plater->reset(); }, ""); | ||||
|             [this](wxCommandEvent&) { m_plater->reset(); }, "delete_all_menu"); | ||||
| 
 | ||||
|         editMenu->AppendSeparator(); | ||||
| 
 | ||||
|         wxMenuItem* item_copy = append_menu_item(editMenu, wxID_ANY, _(L("&Copy")) + "\tCtrl+C", _(L("Copy selection to clipboard")), | ||||
|             [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, "copy_menu"); | ||||
|         wxMenuItem* item_paste = append_menu_item(editMenu, wxID_ANY, _(L("&Paste")) + "\tCtrl+V", _(L("Paste clipboard")), | ||||
|             [this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, "paste_menu"); | ||||
| 
 | ||||
|         Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_select()); }, item_select_all->GetId()); | ||||
|         Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete()); }, item_delete_sel->GetId()); | ||||
|         Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete_all()); }, item_delete_all->GetId()); | ||||
|         Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater->can_copy()); }, item_copy->GetId()); | ||||
|         Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater->can_paste()); }, item_paste->GetId()); | ||||
|     } | ||||
| 
 | ||||
|     // Window menu
 | ||||
|  |  | |||
|  | @ -1405,6 +1405,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [q](SimpleEvent&) { q->copy_selection_to_clipboard(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [q](SimpleEvent&) { q->paste_from_clipboard(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); }); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); | ||||
|  | @ -3699,6 +3701,34 @@ void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) | |||
| 
 | ||||
| void Plater::update_object_menu() { p->update_object_menu(); } | ||||
| 
 | ||||
| void Plater::copy_selection_to_clipboard() | ||||
| { | ||||
|     p->view3D->get_canvas3d()->get_selection().copy_to_clipboard(); | ||||
| } | ||||
| 
 | ||||
| void Plater::paste_from_clipboard() | ||||
| { | ||||
|     p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); | ||||
| } | ||||
| 
 | ||||
| bool Plater::can_paste_from_clipboard() const | ||||
| { | ||||
|     const Selection& selection = p->view3D->get_canvas3d()->get_selection(); | ||||
|     const Selection::Clipboard& clipboard = selection.get_clipboard(); | ||||
|     Selection::EMode mode = clipboard.get_mode(); | ||||
| 
 | ||||
|     if (clipboard.is_empty()) | ||||
|         return false; | ||||
| 
 | ||||
|     if ((mode == Selection::Volume) && !selection.is_from_single_instance()) | ||||
|         return false; | ||||
| 
 | ||||
|     if ((mode == Selection::Instance) && (selection.get_mode() != Selection::Instance)) | ||||
|         return false; | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool Plater::can_delete() const { return p->can_delete(); } | ||||
| bool Plater::can_delete_all() const { return p->can_delete_all(); } | ||||
| bool Plater::can_increase_instances() const { return p->can_increase_instances(); } | ||||
|  | @ -3707,5 +3737,7 @@ bool Plater::can_split_to_objects() const { return p->can_split_to_objects(); } | |||
| bool Plater::can_split_to_volumes() const { return p->can_split_to_volumes(); } | ||||
| bool Plater::can_arrange() const { return p->can_arrange(); } | ||||
| bool Plater::can_layers_editing() const { return p->can_layers_editing(); } | ||||
| bool Plater::can_copy() const { return !is_selection_empty(); } | ||||
| bool Plater::can_paste() const { return can_paste_from_clipboard(); } | ||||
| 
 | ||||
| }}    // namespace Slic3r::GUI
 | ||||
|  |  | |||
|  | @ -182,6 +182,10 @@ public: | |||
|     PrinterTechnology   printer_technology() const; | ||||
|     void                set_printer_technology(PrinterTechnology printer_technology); | ||||
| 
 | ||||
|     void copy_selection_to_clipboard(); | ||||
|     void paste_from_clipboard(); | ||||
|     bool can_paste_from_clipboard() const; | ||||
| 
 | ||||
|     bool can_delete() const; | ||||
|     bool can_delete_all() const; | ||||
|     bool can_increase_instances() const; | ||||
|  | @ -190,6 +194,8 @@ public: | |||
|     bool can_split_to_volumes() const; | ||||
|     bool can_arrange() const; | ||||
|     bool can_layers_editing() const; | ||||
|     bool can_copy() const; | ||||
|     bool can_paste() const; | ||||
| 
 | ||||
| private: | ||||
|     struct priv; | ||||
|  |  | |||
|  | @ -1022,6 +1022,70 @@ bool Selection::requires_local_axes() const | |||
|     return (m_mode == Volume) && is_from_single_instance(); | ||||
| } | ||||
| 
 | ||||
| void Selection::copy_to_clipboard() | ||||
| { | ||||
|     if (!m_valid) | ||||
|         return; | ||||
| 
 | ||||
|     m_clipboard.reset(); | ||||
| 
 | ||||
|     for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content) | ||||
|     { | ||||
|         ModelObject* src_object = m_model->objects[object.first]; | ||||
|         ModelObject* dst_object = m_clipboard.add_object(); | ||||
|         dst_object->name = src_object->name; | ||||
|         dst_object->input_file = src_object->input_file; | ||||
|         dst_object->config = src_object->config; | ||||
| 
 | ||||
|         for (int i : object.second) | ||||
|         { | ||||
|             dst_object->add_instance(*src_object->instances[i]); | ||||
|         } | ||||
| 
 | ||||
|         for (unsigned int i : m_list) | ||||
|         { | ||||
|             const GLVolume* volume = (*m_volumes)[i]; | ||||
|             if ((volume->object_idx() == object.first) && (volume->instance_idx() == *object.second.begin())) | ||||
|             { | ||||
|                 int volume_idx = volume->volume_idx(); | ||||
|                 if ((0 <= volume_idx) && (volume_idx < (int)src_object->volumes.size())) | ||||
|                 { | ||||
|                     ModelVolume* src_volume = src_object->volumes[volume_idx]; | ||||
|                     ModelVolume* dst_volume = dst_object->add_volume(*src_volume); | ||||
|                     dst_volume->set_new_unique_id(); | ||||
|                     dst_volume->config = src_volume->config; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     m_clipboard.set_mode(m_mode); | ||||
| } | ||||
| 
 | ||||
| void Selection::paste_from_clipboard() | ||||
| { | ||||
|     if (!m_valid || m_clipboard.is_empty()) | ||||
|         return; | ||||
| 
 | ||||
|     switch (m_clipboard.get_mode()) | ||||
|     { | ||||
|     case Volume: | ||||
|     { | ||||
|         if (is_from_single_instance()) | ||||
|             paste_volumes_from_clipboard(); | ||||
| 
 | ||||
|         break; | ||||
|     } | ||||
|     case Instance: | ||||
|     { | ||||
|         if (m_mode == Instance) | ||||
|             paste_objects_from_clipboard(); | ||||
| 
 | ||||
|         break; | ||||
|     } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Selection::update_valid() | ||||
| { | ||||
|     m_valid = (m_volumes != nullptr) && (m_model != nullptr); | ||||
|  | @ -1697,5 +1761,43 @@ bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const | |||
|     return count == (unsigned int)m_model->objects[object_idx]->volumes.size(); | ||||
| } | ||||
| 
 | ||||
| void Selection::paste_volumes_from_clipboard() | ||||
| { | ||||
|     int obj_idx = get_object_idx(); | ||||
|     if ((obj_idx < 0) || ((int)m_model->objects.size() <= obj_idx)) | ||||
|         return; | ||||
| 
 | ||||
|     ModelObject* src_object = m_clipboard.get_object(0); | ||||
|     if (src_object != nullptr) | ||||
|     { | ||||
|         ModelObject* dst_object = m_model->objects[obj_idx]; | ||||
| 
 | ||||
|         ModelVolumePtrs volumes; | ||||
|         for (ModelVolume* src_volume : src_object->volumes) | ||||
|         { | ||||
|             ModelVolume* dst_volume = dst_object->add_volume(*src_volume); | ||||
|             dst_volume->config = src_volume->config; | ||||
|             dst_volume->set_new_unique_id(); | ||||
|             dst_volume->translate(10.0, 10.0, 0.0); | ||||
|             volumes.push_back(dst_volume); | ||||
|         } | ||||
|         wxGetApp().obj_list()->paste_volumes_into_list(obj_idx, volumes); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Selection::paste_objects_from_clipboard() | ||||
| { | ||||
|     std::vector<size_t> object_idxs; | ||||
|     const ModelObjectPtrs& src_objects = m_clipboard.get_objects(); | ||||
|     for (const ModelObject* src_object : src_objects) | ||||
|     { | ||||
|         ModelObject* dst_object = m_model->add_object(*src_object); | ||||
|         dst_object->translate(10.0, 10.0, 0.0); | ||||
|         object_idxs.push_back(m_model->objects.size() - 1); | ||||
|     } | ||||
| 
 | ||||
|     wxGetApp().obj_list()->paste_objects_into_list(object_idxs); | ||||
| } | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -138,6 +138,23 @@ public: | |||
|     typedef std::set<int> InstanceIdxsList; | ||||
|     typedef std::map<int, InstanceIdxsList> ObjectIdxsToInstanceIdxsMap; | ||||
| 
 | ||||
|     class Clipboard | ||||
|     { | ||||
|         Model m_model; | ||||
|         Selection::EMode m_mode; | ||||
| 
 | ||||
|     public: | ||||
|         void reset() { m_model.clear_objects(); } | ||||
|         bool is_empty() const { return m_model.objects.empty(); } | ||||
| 
 | ||||
|         ModelObject* add_object() { return m_model.add_object(); } | ||||
|         ModelObject* get_object(unsigned int id) { return (id < (unsigned int)m_model.objects.size()) ? m_model.objects[id] : nullptr; } | ||||
|         const ModelObjectPtrs& get_objects() const { return m_model.objects; } | ||||
| 
 | ||||
|         Selection::EMode get_mode() const { return m_mode; } | ||||
|         void set_mode(Selection::EMode mode) { m_mode = mode; } | ||||
|     }; | ||||
| 
 | ||||
| private: | ||||
|     struct Cache | ||||
|     { | ||||
|  | @ -163,6 +180,7 @@ private: | |||
|     // set of indices to m_volumes
 | ||||
|     IndicesList m_list; | ||||
|     Cache m_cache; | ||||
|     Clipboard m_clipboard; | ||||
|     mutable BoundingBoxf3 m_bounding_box; | ||||
|     mutable bool m_bounding_box_dirty; | ||||
| 
 | ||||
|  | @ -267,6 +285,11 @@ public: | |||
| 
 | ||||
|     bool requires_local_axes() const; | ||||
| 
 | ||||
|     void copy_to_clipboard(); | ||||
|     void paste_from_clipboard(); | ||||
| 
 | ||||
|     const Clipboard& get_clipboard() const { return m_clipboard; } | ||||
| 
 | ||||
| private: | ||||
|     void update_valid(); | ||||
|     void update_type(); | ||||
|  | @ -301,6 +324,9 @@ private: | |||
|     void synchronize_unselected_volumes(); | ||||
|     void ensure_on_bed(); | ||||
|     bool is_from_fully_selected_instance(unsigned int volume_idx) const; | ||||
| 
 | ||||
|     void paste_volumes_from_clipboard(); | ||||
|     void paste_objects_from_clipboard(); | ||||
| }; | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv