mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-04 22:31:02 +00:00
Merge remote-tracking branch 'orca/main' into u1-hf
This commit is contained in:
@@ -48,24 +48,37 @@ bool load_drc(const char *path, TriangleMesh *meshptr)
|
||||
indexed_triangle_set its;
|
||||
|
||||
const PointAttribute *const positions = dracoMesh.GetNamedAttribute(GeometryAttribute::POSITION);
|
||||
if (positions == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "load_drc: the mesh has no POSITION attribute";
|
||||
return false;
|
||||
}
|
||||
size_t num_vertices = positions->size();
|
||||
its.vertices.reserve(num_vertices);
|
||||
for (AttributeValueIndex i(0); i < num_vertices; ++ i) {
|
||||
float pos[3];
|
||||
positions->ConvertValue<float>(i, 3, pos);
|
||||
if (!positions->ConvertValue<float>(i, 3, pos)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "load_drc: invalid vertex position";
|
||||
return false;
|
||||
}
|
||||
its.vertices.emplace_back(pos[0], pos[1], pos[2]);
|
||||
}
|
||||
|
||||
// The Draco decoder does not check face indices against the point count.
|
||||
const uint32_t num_points = dracoMesh.num_points();
|
||||
size_t num_faces = dracoMesh.num_faces();
|
||||
its.indices.reserve(num_faces);
|
||||
for (FaceIndex i(0); i < num_faces; ++ i) {
|
||||
Mesh::Face face = dracoMesh.face(i);
|
||||
|
||||
its.indices.emplace_back(
|
||||
positions->mapped_index(face[0]).value(),
|
||||
positions->mapped_index(face[1]).value(),
|
||||
positions->mapped_index(face[2]).value()
|
||||
);
|
||||
const Mesh::Face &face = dracoMesh.face(i);
|
||||
stl_triangle_vertex_indices facet;
|
||||
for (int k = 0; k < 3; ++ k) {
|
||||
const size_t vertex_idx = face[k].value() < num_points ? positions->mapped_index(face[k]).value() : num_vertices;
|
||||
if (vertex_idx >= num_vertices) {
|
||||
BOOST_LOG_TRIVIAL(error) << "load_drc: invalid vertex index";
|
||||
return false;
|
||||
}
|
||||
facet[k] = static_cast<int>(vertex_idx);
|
||||
}
|
||||
its.indices.emplace_back(facet);
|
||||
}
|
||||
|
||||
*meshptr = TriangleMesh(std::move(its));
|
||||
|
||||
@@ -166,10 +166,15 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s
|
||||
obj_info.uv_map_pngs[face_index] = png_name;
|
||||
}
|
||||
if (data.textureCoordinates.size() > 0) {
|
||||
Vec2f uv0(data.textureCoordinates[uvs[0] * 2], data.textureCoordinates[uvs[0] * 2 + 1]);
|
||||
Vec2f uv1(data.textureCoordinates[uvs[1] * 2], data.textureCoordinates[uvs[1] * 2 + 1]);
|
||||
Vec2f uv2(data.textureCoordinates[uvs[2] * 2], data.textureCoordinates[uvs[2] * 2 + 1]);
|
||||
std::array<Vec2f, 3> uv_array{uv0, uv1, uv2};
|
||||
// A face vertex may omit vt or reference a missing one. Fall back to (0, 0) rather than
|
||||
// skipping the face, so obj_info.uvs stays aligned with the face indices.
|
||||
const int uv_count = static_cast<int>(data.textureCoordinates.size() / OBJ_TEXCOORD_LENGTH);
|
||||
auto uv_at = [&data, uv_count](int idx) -> Vec2f {
|
||||
if (idx < 0 || idx >= uv_count)
|
||||
return Vec2f::Zero();
|
||||
return Vec2f(data.textureCoordinates[idx * OBJ_TEXCOORD_LENGTH], data.textureCoordinates[idx * OBJ_TEXCOORD_LENGTH + 1]);
|
||||
};
|
||||
std::array<Vec2f, 3> uv_array{uv_at(uvs[0]), uv_at(uvs[1]), uv_at(uvs[2])};
|
||||
obj_info.uvs.emplace_back(uv_array);
|
||||
}
|
||||
obj_info.face_colors.emplace_back(face_color);
|
||||
|
||||
@@ -51,19 +51,18 @@ static bool obj_parseline(const char *line, ObjData &data)
|
||||
line = endptr;
|
||||
EATWS();
|
||||
}
|
||||
/*double w = 0;
|
||||
// The optional w is accepted but not stored: only u and v are used.
|
||||
if (*line != 0) {
|
||||
w = strtod(line, &endptr);
|
||||
strtod(line, &endptr);
|
||||
if (endptr == 0 || (*endptr != ' ' && *endptr != '\t' && *endptr != 0))
|
||||
return false;
|
||||
line = endptr;
|
||||
EATWS();
|
||||
}*/
|
||||
}
|
||||
if (*line != 0)
|
||||
return false;
|
||||
data.textureCoordinates.push_back((float)u);
|
||||
data.textureCoordinates.push_back((float)v);
|
||||
//data.textureCoordinates.push_back((float)w);
|
||||
break;
|
||||
}
|
||||
case 'n':
|
||||
@@ -245,7 +244,7 @@ static bool obj_parseline(const char *line, ObjData &data)
|
||||
else
|
||||
-- vertex.normalIdx;
|
||||
if (vertex.textureCoordIdx < 0)
|
||||
vertex.textureCoordIdx += (int)data.textureCoordinates.size() / 3;
|
||||
vertex.textureCoordIdx += (int)data.textureCoordinates.size() / OBJ_TEXCOORD_LENGTH;
|
||||
else
|
||||
-- vertex.textureCoordIdx;
|
||||
data.vertices.push_back(vertex);
|
||||
|
||||
@@ -92,6 +92,7 @@ inline bool operator==(const ObjSmoothingGroup &v1, const ObjSmoothingGroup &v2)
|
||||
}
|
||||
#define OBJ_VERTEX_COLOR_ALPHA 6
|
||||
#define OBJ_VERTEX_LENGTH 7 // x, y, z, color_x,color_y,color_z,color_w
|
||||
#define OBJ_TEXCOORD_LENGTH 2 // u, v
|
||||
#define ONE_FACE_SIZE 4//ONE_FACE format: f 8/4/6 7/3/6 6/2/6 -1/-1/-1
|
||||
struct ObjData {
|
||||
// Version of the data structure for load / store in the private binary format.
|
||||
@@ -100,7 +101,7 @@ struct ObjData {
|
||||
// x, y, z, color_x,color_y,color_z,color_w
|
||||
std::vector<float> coordinates;
|
||||
bool has_vertex_color{false};
|
||||
// u, v, w
|
||||
// u, v
|
||||
std::vector<float> textureCoordinates;
|
||||
// x, y, z
|
||||
std::vector<float> normals;
|
||||
|
||||
@@ -345,16 +345,21 @@ boost::filesystem::path find_bundled_python_home()
|
||||
fs::path bundle_python = fs::path(resources_dir()).parent_path() / "MacOS" / "python";
|
||||
if (valid_python_home(bundle_python))
|
||||
return bundle_python;
|
||||
#elif defined(_WIN32)
|
||||
fs::path exe_python = boost::dll::program_location().parent_path() / "python";
|
||||
if (valid_python_home(exe_python))
|
||||
return exe_python;
|
||||
#else
|
||||
#elif !defined(_WIN32)
|
||||
fs::path linux_python = fs::path(resources_dir()).parent_path() / "lib" / "python";
|
||||
if (valid_python_home(linux_python))
|
||||
return linux_python;
|
||||
#endif
|
||||
|
||||
// Next to the executable: the Windows install layout, and the runtime copied
|
||||
// beside every platform's unit-test binary (tests/slic3rutils/CMakeLists.txt).
|
||||
// The CI test runner only receives the build/tests tree, so the candidates
|
||||
// below -- all of which point into the deps or install trees -- never resolve
|
||||
// there.
|
||||
fs::path exe_python = boost::dll::program_location().parent_path() / "python";
|
||||
if (valid_python_home(exe_python))
|
||||
return exe_python;
|
||||
|
||||
fs::path configured_python = ORCA_BUNDLED_PYTHON_ROOT;
|
||||
if (!configured_python.empty() && valid_python_home(configured_python))
|
||||
return configured_python;
|
||||
|
||||
Reference in New Issue
Block a user