mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Fixing "opening an obj file causes Slic3r to become stuck and use 100% on one core" #221
Extended the OBJ parser to triangulate quads. Higher order polygons are not supported though.
This commit is contained in:
		
							parent
							
								
									8ac1d37b10
								
							
						
					
					
						commit
						1719952f49
					
				
					 2 changed files with 56 additions and 11 deletions
				
			
		|  | @ -26,36 +26,81 @@ bool load_obj(const char *path, Model *model, const char *object_name_in) | ||||||
| 
 | 
 | ||||||
|     // Count the faces and verify, that all faces are triangular.
 |     // Count the faces and verify, that all faces are triangular.
 | ||||||
|     size_t num_faces = 0; |     size_t num_faces = 0; | ||||||
|  | 	size_t num_quads = 0; | ||||||
|     for (size_t i = 0; i < data.vertices.size(); ) { |     for (size_t i = 0; i < data.vertices.size(); ) { | ||||||
|         size_t j = i; |         size_t j = i; | ||||||
|         for (; j < data.vertices.size() && data.vertices[j].coordIdx != -1; ++ j) ; |         for (; j < data.vertices.size() && data.vertices[j].coordIdx != -1; ++ j) ; | ||||||
|         if (i == j) |         if (i == j) | ||||||
|             continue; |             continue; | ||||||
|         if (j - i != 3) { | 		size_t face_vertices = j - i; | ||||||
|             // Non-triangular faces are not supported as of now.
 | 		if (face_vertices != 3 && face_vertices != 4) { | ||||||
|  |             // Non-triangular and non-quad faces are not supported as of now.
 | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         num_faces ++; | 		if (face_vertices == 4) | ||||||
|         i = j; | 			++ num_quads; | ||||||
|  | 		++ num_faces; | ||||||
|  |         i = j + 1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Convert ObjData into STL.
 |     // Convert ObjData into STL.
 | ||||||
|     TriangleMesh mesh; |     TriangleMesh mesh; | ||||||
|     stl_file &stl = mesh.stl; |     stl_file &stl = mesh.stl; | ||||||
|     stl.stats.type = inmemory; |     stl.stats.type = inmemory; | ||||||
|     stl.stats.number_of_facets = num_faces; |     stl.stats.number_of_facets = int(num_faces + num_quads); | ||||||
|     stl.stats.original_num_facets = num_faces; |     stl.stats.original_num_facets = int(num_faces + num_quads); | ||||||
|  |     // stl_allocate clears all the allocated data to zero, all normals are set to zeros as well.
 | ||||||
|     stl_allocate(&stl); |     stl_allocate(&stl); | ||||||
|     size_t i_face = 0; |     size_t i_face = 0; | ||||||
|     for (size_t i = 0; i < data.vertices.size(); ++ i) { |     for (size_t i = 0; i < data.vertices.size(); ++ i) { | ||||||
|         if (data.vertices[i].coordIdx == -1) |         if (data.vertices[i].coordIdx == -1) | ||||||
|             continue; |             continue; | ||||||
|         stl_facet &facet = stl.facet_start[i_face ++]; |         stl_facet &facet = stl.facet_start[i_face ++]; | ||||||
|  |         size_t     num_normals = 0; | ||||||
|  |         stl_normal normal = { 0.f }; | ||||||
|         for (unsigned int v = 0; v < 3; ++ v) { |         for (unsigned int v = 0; v < 3; ++ v) { | ||||||
|             const ObjParser::ObjVertex &vertex = data.vertices[i++]; |             const ObjParser::ObjVertex &vertex = data.vertices[i++]; | ||||||
|             memcpy(&facet.vertex[v].x, &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float)); |             memcpy(&facet.vertex[v].x, &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float)); | ||||||
|             if (vertex.normalIdx != -1) |             if (vertex.normalIdx != -1) { | ||||||
|                 memcpy(&facet.normal.x, &data.normals[vertex.normalIdx*3], 3 * sizeof(float)); |                 normal.x += data.normals[vertex.normalIdx*3]; | ||||||
|  |                 normal.y += data.normals[vertex.normalIdx*3+1]; | ||||||
|  |                 normal.z += data.normals[vertex.normalIdx*3+2]; | ||||||
|  |                 ++ num_normals; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 		if (data.vertices[i].coordIdx != -1) { | ||||||
|  | 			// This is a quad. Produce the other triangle.
 | ||||||
|  | 			stl_facet &facet2 = stl.facet_start[i_face++]; | ||||||
|  |             facet2.vertex[0] = facet.vertex[0]; | ||||||
|  |             facet2.vertex[1] = facet.vertex[2]; | ||||||
|  | 			const ObjParser::ObjVertex &vertex = data.vertices[i++]; | ||||||
|  | 			memcpy(&facet2.vertex[2].x, &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float)); | ||||||
|  | 			if (vertex.normalIdx != -1) { | ||||||
|  |                 normal.x += data.normals[vertex.normalIdx*3]; | ||||||
|  |                 normal.y += data.normals[vertex.normalIdx*3+1]; | ||||||
|  |                 normal.z += data.normals[vertex.normalIdx*3+2]; | ||||||
|  |                 ++ num_normals; | ||||||
|  |             } | ||||||
|  |             if (num_normals == 4) { | ||||||
|  |                 // Normalize an average normal of a quad.
 | ||||||
|  |                 float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z); | ||||||
|  |                 if (len > EPSILON) { | ||||||
|  |                     normal.x /= len; | ||||||
|  |                     normal.y /= len; | ||||||
|  |                     normal.z /= len; | ||||||
|  |                     facet.normal = normal; | ||||||
|  |                     facet2.normal = normal; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else if (num_normals == 3) { | ||||||
|  |             // Normalize an average normal of a triangle.
 | ||||||
|  |             float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z); | ||||||
|  |             if (len > EPSILON) { | ||||||
|  |                 normal.x /= len; | ||||||
|  |                 normal.y /= len; | ||||||
|  |                 normal.z /= len; | ||||||
|  |                 facet.normal = normal; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 	} | 	} | ||||||
|     stl_get_size(&stl); |     stl_get_size(&stl); | ||||||
|  |  | ||||||
|  | @ -346,8 +346,8 @@ bool objparse(const char *path, ObjData &data) | ||||||
| 	} | 	} | ||||||
| 	::fclose(pFile); | 	::fclose(pFile); | ||||||
| 
 | 
 | ||||||
| 	printf("vertices: %d\r\n", data.vertices.size() / 4); | 	// printf("vertices: %d\r\n", data.vertices.size() / 4);
 | ||||||
| 	printf("coords: %d\r\n", data.coordinates.size()); | 	// printf("coords: %d\r\n", data.coordinates.size());
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv