Skip to content

Commit

Permalink
add gyroid surface
Browse files Browse the repository at this point in the history
  • Loading branch information
nodtem66 committed Dec 14, 2019
1 parent 9d07228 commit 9c43d83
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Scaffolder
Generate scaffold from STL file with implicit function (Schwarz P/ Gyroid).
```
Usage: Scaffolder_2 [options]
Options:
-q, --quiet Disable verbose output
-f, --format Output format (OFF,PLY,STL,OBJ) [default: ply]
-i, --input Input file (STL) (Required)
-o, --output Output filename without extension [default: out]
-g, --grid Grid size [default: 100]
--thickness Thickness [default: 1.0]
--border_offset default:2
--coff default:4*PI
--minimum_diameter used for removing small orphaned (between 0-1) [default: 0.25]
```

## Dependencies
- [libigl](https://libigl.github.io/)
- [vcglib](https://github.com/cnr-isti-vclab/vcglib)

## How it works
- Read STL file and finding the boundary box
- Generate the grid and calculate the winding number with STL mesh
- Use winding number to determine the condition for [implicit isosurface function](https://wewanttolearn.wordpress.com/2019/02/03/triply-periodic-minimal-surfaces/)
- Generate the isosurface field in the same-size grid
- Perform [Dual marching cube](https://github.com/dominikwodniok/dualmc) to construct the manifold
- Clean up the duplicated vertices or faces, and abandon the group of connected faces having the diameter below the setting
- Export to the target 3D format

## Reference
- [dualmc](https://github.com/dominikwodniok/dualmc)
- [argparse](https://github.com/jamolnng/argparse)
- [Minimal surface Blog](https://minimalsurfaces.blog/)
6 changes: 5 additions & 1 deletion Scaffolder_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ int main(int argc, const char* argv[])
parser.add_argument("--border_offset", "default:2", false);
parser.add_argument("--coff", "default:4*PI", false);
parser.add_argument("--minimum_diameter", "used for removing small orphaned (between 0-1) [default: 0.25]", false);
parser.add_argument("--surface", "default: schwarzp", false);
try {
parser.parse(argc, argv);
}
Expand All @@ -41,6 +42,7 @@ int main(int argc, const char* argv[])
std::string filename = "out";
std::string format = "ply";
std::string input_file = parser.get<std::string>("input");
std::string surface = "schwarzp";

// get optional parameters
if (parser.exists("quiet")) verbose = parser.get<bool>("quiet");
Expand All @@ -51,6 +53,7 @@ int main(int argc, const char* argv[])
if (parser.exists("border_offset")) border_offset = parser.get<uint16_t>("border_offset");
if (parser.exists("coff")) coff = parser.get<double>("coff");
if (parser.exists("minimum_diameter")) minimum_diameter = parser.get<double>("minimum_diameter");
if (parser.exists("surface")) surface = parser.get<std::string>("surface");

// lowercase format
to_lower(format);
Expand Down Expand Up @@ -95,7 +98,8 @@ int main(int argc, const char* argv[])
grid_size += 2 * (size_t)(border_offset);
// Create iso cuboid condition with boundary box
//Iso_cuboid_condition condition(V1min(0), V1min(1), V1min(2), L(0), L(1), L(2));
Implicit_function fn(schwarzp, coff, thickness);
Function_3& isosurface = get_surface_function(surface);
Implicit_function fn(isosurface, coff, thickness);
if (verbose) std::cout << "Bounding Box: " << V1min.format(CleanFmt) << ' ' << V1max.format(CleanFmt) << std::endl;
if (verbose) std::cout << "Length: " << L << std::endl;
if (verbose) std::cout << "[Generating grid] " << grid_size * grid_size * grid_size << " (" << grid_size << '*' << grid_size << '*' << grid_size << ") ";
Expand Down
32 changes: 31 additions & 1 deletion implicit_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,22 @@ const FT pi = 3.141592653589793238462643383279502884L;
const FT esp = 1e-6;
typedef FT(Function_3)(FT, FT, FT);


inline FT schwarzp(FT x, FT y, FT z) {
return cos(x) + cos(y) + cos(z);
}
inline FT schwarzd(FT x, FT y, FT z) {
return sin(x) * sin(y) * sin(z) + sin(x) * cos(y) * cos(z) + cos(x) * sin(y) * cos(z) + cos(x) * cos(y) * sin(z);
}
inline FT gyroid(FT x, FT y, FT z) {
return sin(x) * cos(y) + sin(y) * cos(z) + sin(z) * cos(x);
}
inline FT lidinoid(FT x, FT y, FT z) {
return 0.5 * (sin(2 * x) * cos(y) * sin(z) + sin(2 * y) * cos(z) * sin(x) + sin(2 * z) * cos(x) * sin(y)) - 0.5 * (cos(2 * x) * cos(2 * y) + cos(2 * y) * cos(2 * z) + cos(2 * z) * cos(2 * x)) + 0.15;
}
inline FT scherk(FT x, FT y, FT z) {
return sinh(x) * sinh(y) - sin(z);
}
inline FT sphere(FT x, FT y, FT z, FT r) {
return x * x + y * y + z * z - r * r;
}
Expand Down Expand Up @@ -106,9 +119,26 @@ class Implicit_function : public Function {
}
};

void to_lower(std::string& s) {
inline void to_lower(std::string& s) {
std::locale loc;
for (std::string::size_type i = 0; i < s.length(); ++i)
s[i] = std::tolower(s[i], loc);
}

inline Function_3& get_surface_function(std::string name) {
to_lower(name);
if (name == "schwarzd") {
return schwarzd;
}
else if (name == "scherk") {
return scherk;
}
else if (name == "lidinoid") {
return lidinoid;
}
else if (name == "gyroid") {
return gyroid;
}
return schwarzp;
}
#endif

0 comments on commit 9c43d83

Please sign in to comment.