VRML: add support for transparency.

pull/463/head
nabijaczleweli 2019-08-10 01:32:24 +02:00 committed by whitequark
parent 837628ea3e
commit d9081b0b08
1 changed files with 106 additions and 72 deletions

View File

@ -1174,6 +1174,14 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename
// Export the mesh as a VRML text file / WRL. // Export the mesh as a VRML text file / WRL.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SolveSpaceUI::ExportMeshAsVrmlTo(FILE *f, const Platform::Path &filename, SMesh *sm) { void SolveSpaceUI::ExportMeshAsVrmlTo(FILE *f, const Platform::Path &filename, SMesh *sm) {
struct STriangleSpan {
STriangle *first, *past_last;
STriangle *begin() const { return first; }
STriangle *end() const { return past_last; }
};
std::string basename = filename.FileStem(); std::string basename = filename.FileStem();
for(auto & c : basename) { for(auto & c : basename) {
if(!(isalnum(c) || ((unsigned)c >= 0x80))) { if(!(isalnum(c) || ((unsigned)c >= 0x80))) {
@ -1185,88 +1193,114 @@ void SolveSpaceUI::ExportMeshAsVrmlTo(FILE *f, const Platform::Path &filename, S
"#Exported from SolveSpace %s\n" "#Exported from SolveSpace %s\n"
"\n" "\n"
"DEF %s Transform {\n" "DEF %s Transform {\n"
" children [\n" " children [",
" Shape {\n"
" appearance Appearance {\n"
" material DEF %s_material Material {\n"
" diffuseColor %f %f %f\n"
" ambientIntensity %f\n"
" transparency 0.0\n"
" }\n"
" }\n"
" geometry IndexedFaceSet {\n"
" colorPerVertex TRUE\n"
" coord Coordinate { point [\n",
PACKAGE_VERSION, PACKAGE_VERSION,
basename.c_str(), basename.c_str());
basename.c_str(),
SS.ambientIntensity,
SS.ambientIntensity,
SS.ambientIntensity,
SS.ambientIntensity);
SPointList spl = {};
for(const auto & tr : sm->l) { std::map<std::uint8_t, std::vector<STriangleSpan>> opacities;
spl.IncrementTagFor(tr.a); STriangle *start = sm->l.begin();
spl.IncrementTagFor(tr.b); std::uint8_t last_opacity = start->meta.color.alpha;
spl.IncrementTagFor(tr.c); for(auto & tr : sm->l) {
} if(tr.meta.color.alpha != last_opacity) {
opacities[last_opacity].push_back(STriangleSpan{start, &tr});
// Output all the vertices. start = &tr;
for(auto sp : spl.l) { last_opacity = start->meta.color.alpha;
fprintf(f, " %f %f %f,\n",
sp.p.x / SS.exportScale,
sp.p.y / SS.exportScale,
sp.p.z / SS.exportScale);
}
fputs(" ] }\n"
" coordIndex [\n", f);
// And now all the triangular faces, in terms of those vertices.
for(const auto & tr : sm->l) {
fprintf(f, " %d, %d, %d, -1,\n",
spl.IndexForPoint(tr.a),
spl.IndexForPoint(tr.b),
spl.IndexForPoint(tr.c));
}
fputs(" ]\n"
" color Color { color [\n", f);
// Output triangle colors.
std::vector<int> triangle_colour_ids;
std::vector<RgbaColor> colours_present;
for(const auto & tr : sm->l) {
const auto colour_itr = std::find_if(colours_present.begin(), colours_present.end(),
[&](const RgbaColor & c) {
return c.Equals(tr.meta.color);
});
if(colour_itr == colours_present.end()) {
fprintf(f, " %.10f %.10f %.10f,\n",
tr.meta.color.redF(),
tr.meta.color.greenF(),
tr.meta.color.blueF());
triangle_colour_ids.push_back(colours_present.size());
colours_present.insert(colours_present.end(), tr.meta.color);
} else {
triangle_colour_ids.push_back(colour_itr - colours_present.begin());
} }
} }
opacities[last_opacity].push_back(STriangleSpan{start, sm->l.end()});
fputs(" ] }\n" for(auto && op : opacities) {
" colorIndex [\n", f); fprintf(f, "\n"
" Shape {\n"
" appearance Appearance {\n"
" material DEF %s_material_%u Material {\n"
" diffuseColor %f %f %f\n"
" ambientIntensity %f\n"
" transparency %f\n"
" }\n"
" }\n"
" geometry IndexedFaceSet {\n"
" colorPerVertex TRUE\n"
" coord Coordinate { point [\n",
basename.c_str(),
(unsigned)op.first,
SS.ambientIntensity,
SS.ambientIntensity,
SS.ambientIntensity,
SS.ambientIntensity,
1.f - ((float)op.first / 255.0f));
for(auto colour_idx : triangle_colour_ids) { SPointList spl = {};
fprintf(f, " %d, %d, %d, -1,\n", colour_idx, colour_idx, colour_idx);
for(const auto & sp : op.second) {
for(const auto & tr : sp) {
spl.IncrementTagFor(tr.a);
spl.IncrementTagFor(tr.b);
spl.IncrementTagFor(tr.c);
}
}
// Output all the vertices.
for(auto sp : spl.l) {
fprintf(f, " %f %f %f,\n",
sp.p.x / SS.exportScale,
sp.p.y / SS.exportScale,
sp.p.z / SS.exportScale);
}
fputs(" ] }\n"
" coordIndex [\n", f);
// And now all the triangular faces, in terms of those vertices.
for(const auto & sp : op.second) {
for(const auto & tr : sp) {
fprintf(f, " %d, %d, %d, -1,\n",
spl.IndexForPoint(tr.a),
spl.IndexForPoint(tr.b),
spl.IndexForPoint(tr.c));
}
}
fputs(" ]\n"
" color Color { color [\n", f);
// Output triangle colors.
std::vector<int> triangle_colour_ids;
std::vector<RgbaColor> colours_present;
for(const auto & sp : op.second) {
for(const auto & tr : sp) {
const auto colour_itr = std::find_if(colours_present.begin(), colours_present.end(),
[&](const RgbaColor & c) {
return c.Equals(tr.meta.color);
});
if(colour_itr == colours_present.end()) {
fprintf(f, " %.10f %.10f %.10f,\n",
tr.meta.color.redF(),
tr.meta.color.greenF(),
tr.meta.color.blueF());
triangle_colour_ids.push_back(colours_present.size());
colours_present.insert(colours_present.end(), tr.meta.color);
} else {
triangle_colour_ids.push_back(colour_itr - colours_present.begin());
}
}
}
fputs(" ] }\n"
" colorIndex [\n", f);
for(auto colour_idx : triangle_colour_ids) {
fprintf(f, " %d, %d, %d, -1,\n", colour_idx, colour_idx, colour_idx);
}
fputs(" ]\n"
" }\n"
" }\n", f);
spl.Clear();
} }
fputs(" ]\n" fputs(" ]\n"
" }\n"
" }\n"
" ]\n"
"}\n", f); "}\n", f);
spl.Clear();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------