Skip to content

Commit

Permalink
Povray viewport (openscad#5393)
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertvanheusden authored Nov 11, 2024
1 parent 681fff1 commit 6baf982
Show file tree
Hide file tree
Showing 16 changed files with 1,526 additions and 13 deletions.
1 change: 0 additions & 1 deletion src/glview/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ class Camera
// (--camera option in commandline mode)
bool locked;

protected:
// Perspective settings
double viewer_distance;
};
8 changes: 4 additions & 4 deletions src/gui/MainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2191,7 +2191,7 @@ void MainWindow::sendToOctoPrint()
userFileName = fileInfo.baseName() + "." + fileFormat.toLower();
}

ExportInfo exportInfo = {.format = exportFileFormat, .sourceFilePath = activeEditor->filepath.toStdString()};
ExportInfo exportInfo = {.format = exportFileFormat, .sourceFilePath = activeEditor->filepath.toStdString(), .camera = &qglview->cam};
exportFileByName(this->root_geom, exportFileName.toStdString(), exportInfo);

try {
Expand Down Expand Up @@ -2246,7 +2246,7 @@ void MainWindow::sendToLocalSlicer()
userFileName = fileInfo.baseName() + fileFormat;
}

ExportInfo exportInfo = {.format = exportFileFormat, .sourceFilePath = activeEditor->filepath.toStdString()};
ExportInfo exportInfo = {.format = exportFileFormat, .sourceFilePath = activeEditor->filepath.toStdString(), .camera = &qglview->cam};
exportFileByName(this->root_geom, exportFileName.toStdString(), exportInfo);

QProcess process(this);
Expand Down Expand Up @@ -2281,7 +2281,7 @@ void MainWindow::sendToPrintService()
const QString exportFilename = exportFile.fileName();

//Render the stl to a temporary file:
ExportInfo exportInfo = {.format = FileFormat::BINARY_STL, .sourceFilePath = activeEditor->filepath.toStdString()};
ExportInfo exportInfo = {.format = FileFormat::BINARY_STL, .sourceFilePath = activeEditor->filepath.toStdString(), .camera = &qglview->cam};
exportFileByName(this->root_geom, exportFilename.toStdString(), exportInfo);

//Create a name that the order process will use to refer to the file. Base it off of the project name
Expand Down Expand Up @@ -2913,7 +2913,7 @@ void MainWindow::actionExport(FileFormat format, const char *type_name, const ch
}
this->export_paths[suffix] = exportFilename;

ExportInfo exportInfo = {.format = format, .sourceFilePath = activeEditor->filepath.toStdString()};
ExportInfo exportInfo = {.format = format, .sourceFilePath = activeEditor->filepath.toStdString(), .camera = &qglview->cam};
// Add options
exportInfo.options = options;

Expand Down
1 change: 1 addition & 0 deletions src/io/export.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct ExportInfo {
FileFormat format;
std::string sourceFilePath; // Full path to the OpenSCAD source file
ExportPdfOptions *options;
const Camera *camera;
};

bool exportFileByName(const std::shared_ptr<const class Geometry>& root_geom, const std::string& filename, const ExportInfo& exportInfo);
Expand Down
26 changes: 23 additions & 3 deletions src/io/export_pov.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "geometry/PolySetUtils.h"
#include "geometry/linalg.h"


void export_pov(const std::shared_ptr<const Geometry>& geom, std::ostream& output, const ExportInfo& exportInfo)
{
std::shared_ptr<const PolySet> ps = PolySetUtils::getGeometryAsPolySet(geom);
Expand All @@ -45,6 +46,7 @@ void export_pov(const std::shared_ptr<const Geometry>& geom, std::ostream& outpu

output << "// Generated by OpenSCAD!\n";
output << "// Source file: " << std::filesystem::path(exportInfo.sourceFilePath).filename().string() << "\n\n";
output << "// Camera settings are at the bottom of this script\n\n";

output << "#version 3.7;\n";
output << "global_settings { assumed_gamma 1.0 }\n";
Expand Down Expand Up @@ -110,9 +112,27 @@ void export_pov(const std::shared_ptr<const Geometry>& geom, std::ostream& outpu
}
}

output << "camera { look_at <" << bbox.center().x() << ", " << bbox.center().y() << ", " << bbox.center().z() << "> "
"location <" << min_x + dx * move_away_factor << ", " << min_y - dy * move_away_factor << ", " << min_z + dz * move_away_factor << "> "
"up <0, 0, 1> right <1, 0, 0> sky <0, 0, 1> rotate <-55, clock * 3, clock + 25> right x*image_width/image_height }\n";
if (exportInfo.camera) {
auto vpt = exportInfo.camera->getVpt();
auto vpr = exportInfo.camera->getVpr();

auto pitch = vpr.x();
auto yaw = vpr.y();
auto roll = vpr.z();

output << "camera { look_at <" << 0 << ", " << 0 << ", " << 0 << ">\n "
"location <" << 0 << ", " << 0 << ", " << exportInfo.camera->viewer_distance << ">\n "
"angle " << exportInfo.camera->fov << " up <0, 1, 0> right <1, 0, 0> sky <0, 1, 0> right -x*image_width/image_height\n"
"translate <" << vpt.x() << ", " << vpt.y() << ", " << vpt.z() << ">\n"
"rotate <" << pitch << ", " << yaw << " + clock * 3, " << roll << " + clock>\n"
"}\n";
}
else {
output << "camera { look_at <" << bbox.center().x() << ", " << bbox.center().y() << ", " << bbox.center().z() << "> "
"location <" << min_x + dx * move_away_factor << ", " << min_y - dy * move_away_factor << ", " << min_z + dz * move_away_factor << "> "
"up <0, 0, 1> right <1, 0, 0> sky <0, 0, 1> rotate <-55, clock * 3, clock + 25> right x*image_width/image_height }\n";
}

output << "#include \"rad_def.inc\"\n";
output << "global_settings { photons { count 20000 autostop 0 jitter .4 } radiosity { Rad_Settings(Radiosity_Normal, off, off) } }\n";
}
7 changes: 4 additions & 3 deletions src/openscad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ bool useGUI()
#endif // OPENSCAD_NOGUI

bool checkAndExport(const std::shared_ptr<const Geometry>& root_geom, unsigned dimensions,
FileFormat format, const bool is_stdout, const std::string& filename, const std::string& input_filename)
FileFormat format, const bool is_stdout, const std::string& filename,
const Camera *const camera, const std::string& input_filename)
{
if (root_geom->getDimension() != dimensions) {
LOG("Current top level object is not a %1$dD object.", dimensions);
Expand All @@ -137,7 +138,7 @@ bool checkAndExport(const std::shared_ptr<const Geometry>& root_geom, unsigned d
LOG("Current top level object is empty.");
return false;
}
ExportInfo exportInfo = {.format = format, .sourceFilePath = input_filename};
ExportInfo exportInfo = {.format = format, .sourceFilePath = input_filename, .camera = camera};
if (is_stdout) {
exportFileStdOut(root_geom, exportInfo);
}
Expand Down Expand Up @@ -445,7 +446,7 @@ int do_export(const CommandLine& cmd, const RenderVariables& render_variables, F

const std::string input_filename = cmd.is_stdin ? "<stdin>" : cmd.filename;
const int dim = fileformat::is3D(export_format) ? 3 : fileformat::is2D(export_format) ? 2 : 0;
if (dim > 0 && !checkAndExport(root_geom, dim, export_format, cmd.is_stdout, filename_str, input_filename)) {
if (dim > 0 && !checkAndExport(root_geom, dim, export_format, cmd.is_stdout, filename_str, &cmd.camera, input_filename)) {
return 1;
}

Expand Down
11 changes: 10 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,16 @@ add_cmdline_test(objexport EXPERIMENTAL OPENSCAD SUFFIX obj FILES $
if (LIB3MF_FOUND)
add_cmdline_test(3mfexport EXPERIMENTAL OPENSCAD SUFFIX 3mf FILES ${EXPORT_3MF_TEST_FILES} ARGS --enable=predictible-output)
endif()
add_cmdline_test(povexport EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold)
add_cmdline_test(povexport-as-is EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold)
add_cmdline_test(povexport-translate-1 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,0,0,0,0,0,140)
add_cmdline_test(povexport-translate-2 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=10,0,0,0,0,0,140)
add_cmdline_test(povexport-translate-3 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,10,0,0,0,0,140)
add_cmdline_test(povexport-translate-4 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,0,10,0,0,0,140)
add_cmdline_test(povexport-rotate-1 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,0,0,90,0,0,140)
add_cmdline_test(povexport-rotate-2 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,0,0,0,90,0,140)
add_cmdline_test(povexport-rotate-3 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,0,0,0,0,90,140)
add_cmdline_test(povexport-distance-1 EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=0,0,0,0,0,0,100)
add_cmdline_test(povexport-all EXPERIMENTAL OPENSCAD SUFFIX pov FILES ${EXPORT_POV_TEST_FILES} ARGS --enable=predictible-output --backend=manifold --camera=1,2,3,4,5,6,7)

# Trivial Export/Import files: Sanity-checks bidirectional file format import/export
set(SIMPLE_EXPORT_IMPORT_2D_FILES ${TEST_SCAD_DIR}/misc/square10.scad)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Generated by OpenSCAD!
// Source file: pov-export.scad

// Camera settings are at the bottom of this script

#version 3.7;
global_settings { assumed_gamma 1.0 }
#declare MATERIAL=finish { specular 0.5 roughness 0.001 reflection{0 0.63 fresnel} ambient 0 diffuse 0.6 conserve_energy }
Expand Down Expand Up @@ -152,6 +154,11 @@ light_source { <80, 5, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 30, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 30, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 30, 30> color rgb <0.2, 0.2, 0.2> }
camera { look_at <5, 5, 5> location <50, -20, 20> up <0, 0, 1> right <1, 0, 0> sky <0, 0, 1> rotate <-55, clock * 3, clock + 25> right x*image_width/image_height }
camera { look_at <0, 0, 0>
location <0, 0, 7>
angle 22.5 up <0, 1, 0> right <1, 0, 0> sky <0, 1, 0> right -x*image_width/image_height
translate <1, 2, 3>
rotate <4, 5 + clock * 3, 6 + clock>
}
#include "rad_def.inc"
global_settings { photons { count 20000 autostop 0 jitter .4 } radiosity { Rad_Settings(Radiosity_Normal, off, off) } }
164 changes: 164 additions & 0 deletions tests/regression/povexport-as-is/pov-export-expected.pov
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Generated by OpenSCAD!
// Source file: pov-export.scad

// Camera settings are at the bottom of this script

#version 3.7;
global_settings { assumed_gamma 1.0 }
#declare MATERIAL=finish { specular 0.5 roughness 0.001 reflection{0 0.63 fresnel} ambient 0 diffuse 0.6 conserve_energy }
#declare MATERIAL_INT=interior{ior 1.32}
polygon { 4,
<-10, 0, 0>, <-10, 0, 10>, <-10, 10, 10>, <-10, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 0, 0>, <-10, 10, 0>, <0, 10, 0>, <-10, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 0, 0>, <-10, 10, 10>, <-10, 10, 0>, <-10, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 0, 0>, <0, 0, 0>, <0, 0, 10>, <-10, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 0, 0>, <0, 0, 10>, <-10, 0, 10>, <-10, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 0, 0>, <0, 10, 0>, <0, 0, 0>, <-10, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 0, 10>, <0, 0, 10>, <-10, 10, 10>, <-10, 0, 10>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 10, 0>, <-10, 10, 10>, <0, 10, 0>, <-10, 10, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 10, 10>, <0, 0, 10>, <0, 10, 10>, <-10, 10, 10>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<-10, 10, 10>, <0, 10, 10>, <0, 10, 0>, <-10, 10, 10>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<0, 0, 0>, <0, 10, 0>, <0, 0, 10>, <0, 0, 0>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<0, 0, 10>, <0, 10, 0>, <0, 10, 10>, <0, 0, 10>
texture { pigment { color rgbf <1, 0.5, 0.25, 0.875> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 0>, <10, 0, 10>, <10, 10, 10>, <10, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 0>, <10, 10, 0>, <20, 10, 0>, <10, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 0>, <10, 10, 10>, <10, 10, 0>, <10, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 0>, <20, 0, 0>, <20, 0, 10>, <10, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 0>, <20, 0, 10>, <10, 0, 10>, <10, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 0>, <20, 10, 0>, <20, 0, 0>, <10, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 0, 10>, <20, 0, 10>, <10, 10, 10>, <10, 0, 10>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 10, 0>, <10, 10, 10>, <20, 10, 0>, <10, 10, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 10, 10>, <20, 0, 10>, <20, 10, 10>, <10, 10, 10>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<10, 10, 10>, <20, 10, 10>, <20, 10, 0>, <10, 10, 10>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<20, 0, 0>, <20, 10, 0>, <20, 0, 10>, <20, 0, 0>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
polygon { 4,
<20, 0, 10>, <20, 10, 0>, <20, 10, 10>, <20, 0, 10>
texture { pigment { color rgbf <0, 0.501961, 0, 0> } }
finish { MATERIAL } interior { MATERIAL_INT }
}
light_source { <-70, -20, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, -20, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, -20, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, 5, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, 5, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, 5, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, 30, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, 30, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <-70, 30, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <5, -20, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <5, -20, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <5, -20, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <5, 5, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <5, 5, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <5, 5, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <5, 30, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <5, 30, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <5, 30, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <80, -20, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <80, -20, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <80, -20, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 5, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 5, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 5, 30> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 30, -20> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 30, 5> color rgb <0.2, 0.2, 0.2> }
light_source { <80, 30, 30> color rgb <0.2, 0.2, 0.2> }
camera { look_at <0, 0, 0>
location <0, 0, 140>
angle 22.5 up <0, 1, 0> right <1, 0, 0> sky <0, 1, 0> right -x*image_width/image_height
translate <0, 0, 0>
rotate <55, 0 + clock * 3, 25 + clock>
}
#include "rad_def.inc"
global_settings { photons { count 20000 autostop 0 jitter .4 } radiosity { Rad_Settings(Radiosity_Normal, off, off) } }
Loading

0 comments on commit 6baf982

Please sign in to comment.