mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -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.
 | ||||
|     size_t num_faces = 0; | ||||
| 	size_t num_quads = 0; | ||||
|     for (size_t i = 0; i < data.vertices.size(); ) { | ||||
|         size_t j = i; | ||||
|         for (; j < data.vertices.size() && data.vertices[j].coordIdx != -1; ++ j) ; | ||||
|         if (i == j) | ||||
|             continue; | ||||
|         if (j - i != 3) { | ||||
|             // Non-triangular faces are not supported as of now.
 | ||||
| 		size_t face_vertices = j - i; | ||||
| 		if (face_vertices != 3 && face_vertices != 4) { | ||||
|             // Non-triangular and non-quad faces are not supported as of now.
 | ||||
|             return false; | ||||
|         } | ||||
|         num_faces ++; | ||||
|         i = j; | ||||
| 		if (face_vertices == 4) | ||||
| 			++ num_quads; | ||||
| 		++ num_faces; | ||||
|         i = j + 1; | ||||
|     } | ||||
| 
 | ||||
|     // Convert ObjData into STL.
 | ||||
|     TriangleMesh mesh; | ||||
|     stl_file &stl = mesh.stl; | ||||
|     stl.stats.type = inmemory; | ||||
|     stl.stats.number_of_facets = num_faces; | ||||
|     stl.stats.original_num_facets = num_faces; | ||||
|     stl.stats.number_of_facets = int(num_faces + num_quads); | ||||
|     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); | ||||
|     size_t i_face = 0; | ||||
|     for (size_t i = 0; i < data.vertices.size(); ++ i) { | ||||
|         if (data.vertices[i].coordIdx == -1) | ||||
|             continue; | ||||
|         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) { | ||||
|             const ObjParser::ObjVertex &vertex = data.vertices[i++]; | ||||
|             memcpy(&facet.vertex[v].x, &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float)); | ||||
|             if (vertex.normalIdx != -1) | ||||
|                 memcpy(&facet.normal.x, &data.normals[vertex.normalIdx*3], 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 (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); | ||||
|  |  | |||
|  | @ -346,8 +346,8 @@ bool objparse(const char *path, ObjData &data) | |||
| 	} | ||||
| 	::fclose(pFile); | ||||
| 
 | ||||
| 	printf("vertices: %d\r\n", data.vertices.size() / 4); | ||||
| 	printf("coords: %d\r\n", data.coordinates.size()); | ||||
| 	// printf("vertices: %d\r\n", data.vertices.size() / 4);
 | ||||
| 	// printf("coords: %d\r\n", data.coordinates.size());
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv