Skip to content

Commit

Permalink
Merge branch 'ext-primitive-voxels' into 3dtiles-content-voxels
Browse files Browse the repository at this point in the history
  • Loading branch information
j9liu committed Feb 10, 2025
2 parents 044a25c + 1beb567 commit 5ef3808
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@

- Fixed parsing URIs that have a scheme followed by `:` instead of `://`.

### v0.44.2 - 2025-02-10

##### Fixes :wrench:

- Fixed a bug in `GltfUtilities::parseGltfCopyright` that could cause a crash when the copyright ends with a semicolon.

### v0.44.1 - 2025-02-03

##### Fixes :wrench:
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ endif()
include("cmake/defaults.cmake")

project(cesium-native
VERSION 0.44.0
VERSION 0.44.2
LANGUAGES CXX C
)

Expand Down
2 changes: 1 addition & 1 deletion CesiumAsync/test/ExamplesAsyncSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ TEST_CASE("AsyncSystem Examples") {
processDownloadedContent(pResponse->data());
std::optional<std::string> maybeUrl =
findReferencedImageUrl(processed);
if (maybeUrl) {
if (!maybeUrl) {
return asyncSystem.createResolvedFuture<
std::shared_ptr<CesiumAsync::IAssetRequest>>(nullptr);
} else {
Expand Down
10 changes: 10 additions & 0 deletions CesiumGltfContent/include/CesiumGltfContent/GltfUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ struct CESIUMGLTFCONTENT_API GltfUtilities {
static std::vector<std::string_view>
parseGltfCopyright(const CesiumGltf::Model& gltf);

/**
* @brief Parse a semicolon-separated string, such as the copyright field of a
* glTF model, and return the individual parts (credits).
*
* @param s The string to parse.
* @return The semicolon-delimited parts.
*/
static std::vector<std::string_view>
parseGltfCopyright(const std::string_view& s);

/**
* @brief Merges all of the glTF's buffers into a single buffer (the first
* one).
Expand Down
50 changes: 36 additions & 14 deletions CesiumGltfContent/src/GltfUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,24 +283,46 @@ GltfUtilities::computeBoundingRegion(

std::vector<std::string_view>
GltfUtilities::parseGltfCopyright(const CesiumGltf::Model& gltf) {
std::vector<std::string_view> result;
if (gltf.asset.copyright) {
const std::string_view copyright = *gltf.asset.copyright;
if (copyright.size() > 0) {
size_t start = 0;
size_t end;
size_t ltrim;
size_t rtrim;
do {
ltrim = copyright.find_first_not_of(" \t", start);
end = copyright.find(';', ltrim);
rtrim = copyright.find_last_not_of(" \t", end - 1);
result.emplace_back(copyright.substr(ltrim, rtrim - ltrim + 1));
start = end + 1;
} while (end != std::string::npos);
return GltfUtilities::parseGltfCopyright(*gltf.asset.copyright);
} else {
return {};
}
}

namespace {
std::string_view trimWhitespace(const std::string_view& s) {
size_t end = s.find_last_not_of(" \t");
if (end == std::string::npos)
return {};
size_t start = s.find_first_not_of(" \t", 0, end + 1);
return s.substr(start, end - start + 1);
}
} // namespace

std::vector<std::string_view>
GltfUtilities::parseGltfCopyright(const std::string_view& s) {
std::vector<std::string_view> result;
if (s.empty())
return result;

size_t start = 0;

auto addPart = [&](size_t end) {
std::string_view trimmed = trimWhitespace(s.substr(start, end - start));
if (!trimmed.empty())
result.emplace_back(std::move(trimmed));
};

for (size_t i = 0, length = s.size(); i < length; ++i) {
if (s[i] == ';') {
addPart(i);
start = i + 1;
}
}

addPart(s.size());

return result;
}

Expand Down
135 changes: 135 additions & 0 deletions CesiumGltfContent/test/TestGltfUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,3 +711,138 @@ TEST_CASE("GltfUtilities::collapseToSingleBuffer") {
CHECK(m.bufferViews[2].byteLength == 100);
}
}

TEST_CASE("GltfUtilities::parseGltfCopyright") {
SUBCASE("properly parses multiple copyright entries") {
Model model;
model.asset.copyright = "Test;a;b;c";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 4);
CHECK(result[0] == "Test");
CHECK(result[1] == "a");
CHECK(result[2] == "b");
CHECK(result[3] == "c");
}

SUBCASE("properly parses a single copyright entry") {
Model model;
model.asset.copyright = "Test";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 1);
CHECK(result[0] == "Test");
}

SUBCASE("properly parses an entry with a trailing semicolon") {
Model model;
model.asset.copyright = "Test;a;b;c;";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 4);
CHECK(result[0] == "Test");
CHECK(result[1] == "a");
CHECK(result[2] == "b");
CHECK(result[3] == "c");
}

SUBCASE("properly parses entries with whitespace") {
Model model;
model.asset.copyright = "\tTest;a\t ;\tb;\t \tc\t;\t ";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 4);
CHECK(result[0] == "Test");
CHECK(result[1] == "a");
CHECK(result[2] == "b");
CHECK(result[3] == "c");
}

SUBCASE("properly parses an empty string") {
Model model;
model.asset.copyright = "";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 0);
}

SUBCASE("properly parses whitespace only") {
Model model;
model.asset.copyright = " \t \t";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 0);
}

SUBCASE("properly parses empty parts in the middle") {
Model model;
model.asset.copyright = "a;;b";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 2);
CHECK(result[0] == "a");
CHECK(result[1] == "b");
}

SUBCASE("properly parses whitespace parts in the middle") {
Model model;
model.asset.copyright = "a;\t;b";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 2);
CHECK(result[0] == "a");
CHECK(result[1] == "b");
}

SUBCASE("properly parses empty parts at the start") {
Model model;
model.asset.copyright = ";a;b";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 2);
CHECK(result[0] == "a");
CHECK(result[1] == "b");
}

SUBCASE("properly parses whitespace parts at the start") {
Model model;
model.asset.copyright = "\t;a;b";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 2);
CHECK(result[0] == "a");
CHECK(result[1] == "b");
}

SUBCASE("properly parses empty parts at the end") {
Model model;
model.asset.copyright = "a;b;";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 2);
CHECK(result[0] == "a");
CHECK(result[1] == "b");
}

SUBCASE("properly parses whitespace parts at the end") {
Model model;
model.asset.copyright = "a;b;\t";
std::vector<std::string_view> result =
GltfUtilities::parseGltfCopyright(model);

REQUIRE(result.size() == 2);
CHECK(result[0] == "a");
CHECK(result[1] == "b");
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cesium-native",
"version": "0.44.0",
"version": "0.44.2",
"description": "Cesium 3D Geospatial for C++",
"main": "index.js",
"directories": {
Expand Down

0 comments on commit 5ef3808

Please sign in to comment.