Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions src/ldrawloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@

#include "ldrawloader.hpp"

#include <immintrin.h>

#include <cmath>
#include <cstdlib>
#include <cfloat>

#include <algorithm>
#include <assert.h>
#include <intrin.h>
#include <stdlib.h>

#include <filesystem>

#define LDR_DEBUG_FLAG_FILELOAD 1
#define LDR_DEBUG_FLAG 0
Expand Down Expand Up @@ -526,7 +531,7 @@ class Mesh
sides[i] = vec_normalize(vec_sub(positions[triangles[t * 3 + i]], positions[triangles[t * 3 + (i + 1) % 3]]));
}
for(uint32_t i = 0; i < 3; i++) {
float angle = fabsf(vec_dot(vec_neg(sides[i]), sides[(i + 1) % 3]));
float angle = std::fabs(vec_dot(vec_neg(sides[i]), sides[(i + 1) % 3]));
if(angle < minAngle) {
minAngle = angle;
corner = i;
Expand Down Expand Up @@ -2094,7 +2099,7 @@ class MeshUtils
}

// just in case things go beyond south
if(isnan(chamferModifier) || isinf(chamferModifier) || (edgeA.isOpen() && edgeB.isOpen())) {
if(std::isnan(chamferModifier) || std::isinf(chamferModifier) || (edgeA.isOpen() && edgeB.isOpen())) {
chamferModifier = 0;
}

Expand Down Expand Up @@ -2500,7 +2505,7 @@ class MeshUtils
i = i;
}

memset(localOutIdx.data(), LDR_INVALID_IDX, maxOutCount * sizeof(uint32_t));
std::memset(localOutIdx.data(), LDR_INVALID_IDX, maxOutCount * sizeof(uint32_t));

for(uint32_t o = 0; o < outInfo.count; o++) {
uint32_t rvtx = builder.vtxOutIndices[outInfo.begin + o];
Expand Down Expand Up @@ -2960,10 +2965,31 @@ LdrResult Loader::registerInternalPart(const char* filename, const std::string&
return result;
}

std::filesystem::path normalizePath(const std::string& messyPath)
{
std::vector<char> path_copy{messyPath.begin(), messyPath.end()};
#if defined(WINDOWS) || defined(WIN32)
// Do nothing here.
#else
for (size_t i = 0 ; i < path_copy.size() ; ++i) {
if (path_copy[i] == '\\') {
path_copy[i] = '/';
}
}
#endif
std::filesystem::path path{path_copy.begin(), path_copy.end()};
std::filesystem::path canonicalPath = std::filesystem::weakly_canonical(path);
return canonicalPath.make_preferred();
}

bool Loader::findLibraryFile(const char* filename, std::string& foundname, bool allowPrimitives, bool& isPrimitive)
{
auto fname{normalizePath(filename)};

for(uint32_t i = allowPrimitives ? (m_config.partHiResPrimitives ? 0 : 1) : PRIMITIVE_PATHS; i < SEARCH_PATHS; i++) {
foundname = m_searchPaths[i] + filename;
std::filesystem::path p{m_searchPaths[i]};
p /= fname;
foundname = p.lexically_normal().native();

FILE* f = fopen(foundname.c_str(), "rb");
bool found = f != nullptr;
Expand Down Expand Up @@ -3531,7 +3557,7 @@ LdrResult Loader::loadData(LdrPart& part, LdrRenderPart& renderPart, const char*
float distC = vec_length(vec_sub(vecA, vecC));
float dist = std::min(std::min(distA, distB), distC);

float dotA = fabsf(vec_dot(vec_normalize(vec_sub(vecB, vecA)), vec_normalize(vec_sub(vecC, vecA))));
float dotA = std::fabs(vec_dot(vec_normalize(vec_sub(vecB, vecA)), vec_normalize(vec_sub(vecC, vecA))));
if(dotA <= Loader::NO_AREA_TRIANGLE_DOT && dist > Loader::MIN_MERGE_EPSILON) {
uint32_t vidx = (uint32_t)builder.positions.size();
uint32_t tidx = (uint32_t)builder.triangles.size() / 3;
Expand Down Expand Up @@ -3581,8 +3607,8 @@ LdrResult Loader::loadData(LdrPart& part, LdrRenderPart& renderPart, const char*

material = fixupMaterialID(material);

float dotA = fabsf(vec_dot(vec_normalize(vec_sub(vecB, vecA)), vec_normalize(vec_sub(vecC, vecA))));
float dotD = fabsf(vec_dot(vec_normalize(vec_sub(vecA, vecD)), vec_normalize(vec_sub(vecC, vecD))));
float dotA = std::fabs(vec_dot(vec_normalize(vec_sub(vecB, vecA)), vec_normalize(vec_sub(vecC, vecA))));
float dotD = std::fabs(vec_dot(vec_normalize(vec_sub(vecA, vecD)), vec_normalize(vec_sub(vecC, vecD))));
if(dotA <= Loader::NO_AREA_TRIANGLE_DOT || dotD <= Loader::NO_AREA_TRIANGLE_DOT) {
uint32_t vidx = (uint32_t)builder.positions.size();
uint32_t tidx = (uint32_t)builder.triangles.size() / 3;
Expand Down Expand Up @@ -4404,7 +4430,7 @@ void Loader::fixPart(LdrPartID partid)
fillBuilderPart(builder, partid);

deinitPart(part);
memset(&part, 0, sizeof(LdrPart));
std::memset(&part, 0, sizeof(LdrPart));

MeshUtils::fixBuilderPart(builder, m_config);

Expand Down Expand Up @@ -4653,7 +4679,7 @@ void Loader::BuilderPart::getCanonicalQuad(uint32_t t, uint32_t quad[4]) const

LDR_API void ldrGetDefaultCreateInfo(LdrLoaderCreateInfo* info)
{
memset(info, 0, sizeof(LdrLoaderCreateInfo));
std::memset(info, 0, sizeof(LdrLoaderCreateInfo));
info->partHiResPrimitives = LDR_FALSE;
info->partFixMode = LDR_PART_FIX_NONE;
info->partFixTjunctions = LDR_TRUE;
Expand Down
10 changes: 10 additions & 0 deletions src/ldrawloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#pragma once

#include <stdint.h>
#include <stddef.h> // size_t

// LDR_CFG_THREADSAFE
// Enabled: you can load parts/models from multiple threads
Expand Down Expand Up @@ -93,7 +94,16 @@ extern "C" {
#define LDR_INVALID_IDX uint32_t(~0)
#define LDR_INVALID_SHAPETYPE 0

#if defined(WINDOWS) || defined(WIN32)
#define LDR_RESTRICT __restrict
#else
// XXX: This isn't the perfect soluton. Looks like GCC/Clang are strict about
// qv-qualifiers producing incompatible types, which messes with function
// resultion when values are marked LDR_RESTRICT and then passed to
// functions where the parameters are not marked.
// So to keep things simple for now, disable this.
#define LDR_RESTRICT
#endif

typedef enum LdrResult : int32_t
{
Expand Down
7 changes: 5 additions & 2 deletions src/ldrawloader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include <thread>
#endif

#include <cstring>
#include <cfloat>

#include <string>
#include <unordered_map>
#include <unordered_set>
Expand Down Expand Up @@ -329,7 +332,7 @@ struct Loader

BitArray() {}
BitArray(uint32_t num, bool value) { resize(num, value); }
void clear() { memset(data, 0, sizeof(uint64_t) * (num_allocated / 64)); }
void clear() { std::memset(data, 0, sizeof(uint64_t) * (num_allocated / 64)); }

uint32_t size() const { return num; }

Expand All @@ -344,7 +347,7 @@ struct Loader

uint32_t idx = num_old / 64;
uint32_t num_delta = numNew - num_old;
memset(data + idx, value ? 0xFFFFFFFF : 0, sizeof(uint64_t) * (num_delta / 64));
std::memset(data + idx, value ? 0xFFFFFFFF : 0, sizeof(uint64_t) * (num_delta / 64));
}
}

Expand Down