-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add OBJ export functionality to SFCGAL
This commit introduces a new feature to export SFCGAL geometries to OBJ format. The implementation includes: - New namespace SFCGAL::io::OBJ with export functions - Support for all SFCGAL geometry types - Multiple export methods: to stream, file, string, and C-style buffer - Comprehensive unit tests Key features: 1. Exports points, lines, polygons, and complex 3D geometries 2. Handles both 2D (z=0.0) and 3D geometries 3. Provides a C-compatible API for integration with other software 4. Includes error handling for invalid geometries and file operations The OBJ export functionality allows SFCGAL users to easily convert geometries to a widely supported 3D format, facilitating interoperability with various 3D modeling and visualization software. Files added: - include/SFCGAL/io/OBJ.h - src/io/OBJ.cpp - test/unit/SFCGAL/io/OBJTest.cpp - test/data/objfiles directory
- Loading branch information
1 parent
c03c1bd
commit 94f3747
Showing
27 changed files
with
713 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
#include "SFCGAL/io/OBJ.h" | ||
#include "SFCGAL/GeometryCollection.h" | ||
#include "SFCGAL/LineString.h" | ||
#include "SFCGAL/MultiLineString.h" | ||
#include "SFCGAL/MultiPoint.h" | ||
#include "SFCGAL/MultiPolygon.h" | ||
#include "SFCGAL/MultiSolid.h" | ||
#include "SFCGAL/Point.h" | ||
#include "SFCGAL/Polygon.h" | ||
#include "SFCGAL/PolyhedralSurface.h" | ||
#include "SFCGAL/Solid.h" | ||
#include "SFCGAL/Triangle.h" | ||
#include "SFCGAL/TriangulatedSurface.h" | ||
#include <fstream> | ||
#include <functional> | ||
#include <sstream> | ||
#include <vector> | ||
|
||
namespace SFCGAL { | ||
namespace io { | ||
namespace OBJ { | ||
|
||
void | ||
save(const Geometry &geom, std::ostream &out) | ||
{ | ||
std::vector<Point> all_points; | ||
std::vector<std::vector<size_t>> all_faces; | ||
std::vector<std::vector<size_t>> all_lines; | ||
std::vector<size_t> all_points_indices; | ||
|
||
std::function<void(const Geometry &)> process_geometry = | ||
[&](const Geometry &g) { | ||
switch (g.geometryTypeId()) { | ||
case TYPE_POINT: { | ||
const Point &p = g.as<Point>(); | ||
all_points.push_back(p); | ||
all_points_indices.push_back(all_points.size()); | ||
break; | ||
} | ||
case TYPE_LINESTRING: { | ||
const LineString &ls = g.as<LineString>(); | ||
std::vector<size_t> line; | ||
for (size_t i = 0; i < ls.numPoints(); ++i) { | ||
all_points.push_back(ls.pointN(i)); | ||
line.push_back(all_points.size()); | ||
} | ||
all_lines.push_back(line); | ||
break; | ||
} | ||
case TYPE_TRIANGLE: { | ||
const Triangle &tri = g.as<Triangle>(); | ||
std::vector<size_t> face; | ||
for (int i = 0; i < 3; ++i) { | ||
all_points.push_back(tri.vertex(i)); | ||
face.push_back(all_points.size()); | ||
} | ||
all_faces.push_back(face); | ||
break; | ||
} | ||
case TYPE_POLYGON: { | ||
const Polygon &poly = g.as<Polygon>(); | ||
std::vector<size_t> face; | ||
for (size_t i = 0; i < poly.exteriorRing().numPoints() - 1; ++i) { | ||
all_points.push_back(poly.exteriorRing().pointN(i)); | ||
face.push_back(all_points.size()); | ||
} | ||
all_faces.push_back(face); | ||
break; | ||
} | ||
case TYPE_TRIANGULATEDSURFACE: { | ||
const TriangulatedSurface &ts = g.as<TriangulatedSurface>(); | ||
for (size_t i = 0; i < ts.numTriangles(); ++i) { | ||
process_geometry(ts.triangleN(i)); | ||
} | ||
break; | ||
} | ||
case TYPE_POLYHEDRALSURFACE: { | ||
const PolyhedralSurface &ps = g.as<PolyhedralSurface>(); | ||
for (size_t i = 0; i < ps.numPolygons(); ++i) { | ||
process_geometry(ps.polygonN(i)); | ||
} | ||
break; | ||
} | ||
case TYPE_SOLID: { | ||
const Solid &solid = g.as<Solid>(); | ||
process_geometry(solid.exteriorShell()); | ||
break; | ||
} | ||
case TYPE_MULTIPOINT: | ||
case TYPE_MULTILINESTRING: | ||
case TYPE_MULTIPOLYGON: | ||
case TYPE_MULTISOLID: | ||
case TYPE_GEOMETRYCOLLECTION: { | ||
const GeometryCollection &gc = g.as<GeometryCollection>(); | ||
for (size_t i = 0; i < gc.numGeometries(); ++i) { | ||
process_geometry(gc.geometryN(i)); | ||
} | ||
break; | ||
} | ||
default: | ||
throw std::runtime_error("Unsupported geometry type: " + | ||
g.geometryType()); | ||
} | ||
}; | ||
|
||
process_geometry(geom); | ||
|
||
for (const auto &p : all_points) { | ||
out << "v " << p.x() << " " << p.y() << " " << (p.is3D() ? p.z() : 0.0) | ||
<< "\n"; | ||
} | ||
|
||
for (size_t idx : all_points_indices) { | ||
out << "p " << idx << "\n"; | ||
} | ||
|
||
for (const auto &line : all_lines) { | ||
out << "l"; | ||
for (size_t idx : line) { | ||
out << " " << idx; | ||
} | ||
out << "\n"; | ||
} | ||
|
||
for (const auto &face : all_faces) { | ||
out << "f"; | ||
for (size_t idx : face) { | ||
out << " " << idx; | ||
} | ||
out << "\n"; | ||
} | ||
} | ||
|
||
void | ||
save(const Geometry &geom, const std::string &filename) | ||
{ | ||
std::ofstream out(filename); | ||
if (!out) { | ||
throw std::runtime_error("Unable to open file " + filename + | ||
" for writing."); | ||
} | ||
save(geom, out); | ||
} | ||
|
||
std::string | ||
saveToString(const Geometry &geom) | ||
{ | ||
std::ostringstream oss; | ||
save(geom, oss); | ||
return oss.str(); | ||
} | ||
|
||
void | ||
saveToBuffer(const Geometry &geom, char *buffer, size_t *size) | ||
{ | ||
std::string result = saveToString(geom); | ||
if (buffer && *size >= result.size()) { | ||
std::copy(result.begin(), result.end(), buffer); | ||
*size = result.size(); | ||
} else { | ||
*size = result.size(); | ||
} | ||
} | ||
|
||
} // namespace OBJ | ||
} // namespace io | ||
} // namespace SFCGAL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright (c) 2024-2024, Oslandia. | ||
// SPDX-License-Identifier: LGPL-2.0-or-later | ||
|
||
#ifndef _SFCGAL_IO_OBJ_H_ | ||
#define _SFCGAL_IO_OBJ_H_ | ||
|
||
#include <SFCGAL/Geometry.h> | ||
#include <ostream> | ||
#include <string> | ||
|
||
namespace SFCGAL { | ||
namespace io { | ||
namespace OBJ { | ||
|
||
/** | ||
* @brief Saves a geometry to an OBJ format stream. | ||
* @ingroup io | ||
* | ||
* @param[in] geom The geometry to save | ||
* @param[out] out The output stream | ||
* @throws std::runtime_error If the geometry is invalid or unsupported | ||
*/ | ||
void | ||
save(const Geometry &geom, std::ostream &out); | ||
|
||
/** | ||
* @brief Saves a geometry to an OBJ file. | ||
* @ingroup io | ||
* | ||
* @param[in] geom The geometry to save | ||
* @param[in] filename The name of the file to save to | ||
* @throws std::runtime_error If the file cannot be opened or the geometry is | ||
* invalid | ||
*/ | ||
void | ||
save(const Geometry &geom, const std::string &filename); | ||
|
||
/** | ||
* @brief Saves a geometry to an OBJ format string. | ||
* @ingroup io | ||
* | ||
* @param[in] geom The geometry to save | ||
* @return The OBJ format string | ||
* @throws std::runtime_error If the geometry is invalid or unsupported | ||
*/ | ||
std::string | ||
saveToString(const Geometry &geom); | ||
|
||
/** | ||
* @brief Saves a geometry to an OBJ format buffer (C API). | ||
* @ingroup io | ||
* | ||
* @param[in] geom The geometry to save | ||
* @param[out] buffer The buffer to write to | ||
* @param[in,out] size On input, the size of the buffer. On output, the number | ||
* of bytes written (or required if buffer is null) | ||
* @throws std::runtime_error If the geometry is invalid or unsupported | ||
*/ | ||
void | ||
saveToBuffer(const Geometry &geom, char *buffer, size_t *size); | ||
|
||
} // namespace OBJ | ||
} // namespace io | ||
} // namespace SFCGAL | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
v 2 3 0 | ||
v 0 0 0 | ||
v 1 0 0 | ||
v 1 1 0 | ||
p 1 | ||
f 2 3 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
v 2 3 5 | ||
v 0 0 6 | ||
v 1 0 6 | ||
v 1 1 6 | ||
p 1 | ||
f 2 3 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
v 0 0 0 | ||
v 1 1 0 | ||
v 2 2 0 | ||
l 1 2 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
v 0 0 0 | ||
v 1 1 1 | ||
v 2 2 2 | ||
l 1 2 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
v 0 0 0 | ||
v 1 1 0 | ||
v 2 2 0 | ||
v 3 3 0 | ||
l 1 2 | ||
l 3 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
v 0 0 0 | ||
v 1 1 1 | ||
v 2 2 2 | ||
v 3 3 3 | ||
l 1 2 | ||
l 3 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
v 1 1 0 | ||
v 2 2 0 | ||
p 1 | ||
p 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
v 1 1 1 | ||
v 2 2 2 | ||
p 1 | ||
p 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
v 0 0 0 | ||
v 1 0 0 | ||
v 1 1 0 | ||
v 0 1 0 | ||
v 2 2 0 | ||
v 3 2 0 | ||
v 3 3 0 | ||
v 2 3 0 | ||
f 1 2 3 4 | ||
f 5 6 7 8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
v 0 0 0 | ||
v 1 0 0 | ||
v 1 1 0 | ||
v 0 1 0 | ||
v 2 2 2 | ||
v 3 2 2 | ||
v 3 3 2 | ||
v 2 3 2 | ||
f 1 2 3 4 | ||
f 5 6 7 8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
v 0 0 0 | ||
v 0 1 0 | ||
v 1 1 0 | ||
v 1 0 0 | ||
v 0 0 0 | ||
v 1 0 0 | ||
v 1 0 0 | ||
v 0 0 0 | ||
v 0 0 0 | ||
v 1 0 0 | ||
v 1 0 0 | ||
v 0 0 0 | ||
v 1 1 0 | ||
v 0 1 0 | ||
v 0 1 0 | ||
v 1 1 0 | ||
v 1 0 0 | ||
v 1 1 0 | ||
v 1 1 0 | ||
v 1 0 0 | ||
v 0 0 0 | ||
v 0 0 0 | ||
v 0 1 0 | ||
v 0 1 0 | ||
v 2 4 0 | ||
v 2 5 0 | ||
v 3 5 0 | ||
v 3 4 0 | ||
v 2 4 0 | ||
v 3 4 0 | ||
v 3 5 0 | ||
v 2 5 0 | ||
v 2 4 0 | ||
v 3 4 0 | ||
v 3 4 0 | ||
v 2 4 0 | ||
v 3 5 0 | ||
v 2 5 0 | ||
v 2 5 0 | ||
v 3 5 0 | ||
v 3 4 0 | ||
v 3 5 0 | ||
v 3 5 0 | ||
v 3 4 0 | ||
v 2 4 0 | ||
v 2 4 0 | ||
v 2 5 0 | ||
v 2 5 0 | ||
f 1 2 3 4 | ||
f 5 6 7 8 | ||
f 9 10 11 12 | ||
f 13 14 15 16 | ||
f 17 18 19 20 | ||
f 21 22 23 24 | ||
f 25 26 27 28 | ||
f 29 30 31 32 | ||
f 33 34 35 36 | ||
f 37 38 39 40 | ||
f 41 42 43 44 | ||
f 45 46 47 48 |
Oops, something went wrong.