mirror of https://github.com/vitalif/openscad
first working version of opencsg png export from gui binary
also guiopencsgtest introduced. passes 100% of 'normal' testsfelipesanches-svg
parent
8738cdc034
commit
9896b6f15e
|
@ -13,10 +13,7 @@ public:
|
|||
|
||||
#ifdef ENABLE_OPENCSG
|
||||
|
||||
#include <opencsg.h>
|
||||
#include "OpenCSGRenderer.h"
|
||||
#include "csgterm.h"
|
||||
#include "csgtermnormalizer.h"
|
||||
|
||||
class CsgInfo_OpenCSG : public CsgInfo
|
||||
{
|
||||
|
|
|
@ -393,13 +393,3 @@ void GLView::showCrosshairs()
|
|||
glEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
void paintGL(); //
|
||||
bool save(const char *filename); //
|
||||
//bool save(std::ostream &output); // not implemented in qgl?
|
||||
|
||||
GLint shaderinfo[11]; //
|
||||
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ class OpenCSGPrim : public OpenCSG::Primitive
|
|||
public:
|
||||
OpenCSGPrim(OpenCSG::Operation operation, unsigned int convexity) :
|
||||
OpenCSG::Primitive(operation, convexity) { }
|
||||
shared_ptr<PolySet> ps;
|
||||
boost::shared_ptr<PolySet> ps;
|
||||
Transform3d m;
|
||||
PolySet::csgmode_e csgmode;
|
||||
virtual void render() {
|
||||
|
@ -71,6 +71,10 @@ void OpenCSGRenderer::draw(bool /*showfaces*/, bool showedges) const
|
|||
}
|
||||
}
|
||||
|
||||
#include "CGALEvaluator.h"
|
||||
#include "CSGTermEvaluator.h"
|
||||
#include "csgtermnormalizer.h"
|
||||
|
||||
void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
||||
bool highlight, bool background) const
|
||||
{
|
||||
|
@ -129,3 +133,54 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
|
|||
}
|
||||
std::for_each(primitives.begin(), primitives.end(), del_fun<OpenCSG::Primitive>());
|
||||
}
|
||||
|
||||
// miscellaneous code to prep OpenCSG render.
|
||||
// returns 0 on success, 1 on failure
|
||||
// csgInfo gets modified
|
||||
int opencsg_prep( const Tree &tree, const AbstractNode *root_node, CsgInfo_OpenCSG &csgInfo )
|
||||
{
|
||||
CGALEvaluator cgalevaluator(tree);
|
||||
CSGTermEvaluator evaluator(tree, &cgalevaluator.psevaluator);
|
||||
boost::shared_ptr<CSGTerm> root_raw_term = evaluator.evaluateCSGTerm(*root_node,
|
||||
csgInfo.highlight_terms,
|
||||
csgInfo.background_terms);
|
||||
|
||||
if (!root_raw_term) {
|
||||
std::cerr << "Error: CSG generation failed! (no top level object found)\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// CSG normalization
|
||||
CSGTermNormalizer normalizer(5000);
|
||||
csgInfo.root_norm_term = normalizer.normalize(root_raw_term);
|
||||
if (csgInfo.root_norm_term) {
|
||||
csgInfo.root_chain = new CSGChain();
|
||||
csgInfo.root_chain->import(csgInfo.root_norm_term);
|
||||
fprintf(stderr, "Normalized CSG tree has %d elements\n", int(csgInfo.root_chain->polysets.size()));
|
||||
}
|
||||
else {
|
||||
csgInfo.root_chain = NULL;
|
||||
fprintf(stderr, "WARNING: CSG normalization resulted in an empty tree\n");
|
||||
}
|
||||
|
||||
if (csgInfo.highlight_terms.size() > 0) {
|
||||
std::cerr << "Compiling highlights (" << csgInfo.highlight_terms.size() << " CSG Trees)...\n";
|
||||
|
||||
csgInfo.highlights_chain = new CSGChain();
|
||||
for (unsigned int i = 0; i < csgInfo.highlight_terms.size(); i++) {
|
||||
csgInfo.highlight_terms[i] = normalizer.normalize(csgInfo.highlight_terms[i]);
|
||||
csgInfo.highlights_chain->import(csgInfo.highlight_terms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (csgInfo.background_terms.size() > 0) {
|
||||
std::cerr << "Compiling background (" << csgInfo.background_terms.size() << " CSG Trees)...\n";
|
||||
|
||||
csgInfo.background_chain = new CSGChain();
|
||||
for (unsigned int i = 0; i < csgInfo.background_terms.size(); i++) {
|
||||
csgInfo.background_terms[i] = normalizer.normalize(csgInfo.background_terms[i]);
|
||||
csgInfo.background_chain->import(csgInfo.background_terms[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,4 +20,9 @@ private:
|
|||
GLint *shaderinfo;
|
||||
};
|
||||
|
||||
#include "Tree.h"
|
||||
#include "CsgInfo.h"
|
||||
// should we refactor this into the renderer class?
|
||||
int opencsg_prep( const Tree &tree, const AbstractNode *root_node, CsgInfo_OpenCSG &csgInfo );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define EXPORT_H_
|
||||
|
||||
#include <iostream>
|
||||
#include "Tree.h"
|
||||
|
||||
#ifdef ENABLE_CGAL
|
||||
|
||||
|
@ -9,7 +10,7 @@ void export_stl(class CGAL_Nef_polyhedron *root_N, std::ostream &output);
|
|||
void export_off(CGAL_Nef_polyhedron *root_N, std::ostream &output);
|
||||
void export_dxf(CGAL_Nef_polyhedron *root_N, std::ostream &output);
|
||||
void export_png_with_cgal(CGAL_Nef_polyhedron *root_N, std::ostream &output);
|
||||
void export_png_with_opencsg(CGAL_Nef_polyhedron *root_N, std::ostream &output);
|
||||
void export_png_with_opencsg(Tree &tree, std::ostream &output);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -46,15 +46,50 @@ void export_png_with_cgal(CGAL_Nef_polyhedron *root_N, std::ostream &output)
|
|||
csgInfo.glview->save(output);
|
||||
}
|
||||
|
||||
void export_png_with_opencsg(CGAL_Nef_polyhedron *root_N, std::ostream &output)
|
||||
#ifdef ENABLE_OPENCSG
|
||||
#include "OpenCSGRenderer.h"
|
||||
#include <opencsg.h>
|
||||
#endif
|
||||
|
||||
void export_png_with_opencsg(Tree &tree, std::ostream &output)
|
||||
{
|
||||
CsgInfo csgInfo;
|
||||
#ifdef ENABLE_OPENCSG
|
||||
CsgInfo_OpenCSG csgInfo = CsgInfo_OpenCSG();
|
||||
AbstractNode const *root_node = tree.root();
|
||||
int result = opencsg_prep( tree, root_node, csgInfo );
|
||||
if ( result == 1 ) {
|
||||
return;
|
||||
fprintf(stderr,"Couldn't init OpenCSG chainsn");
|
||||
}
|
||||
|
||||
try {
|
||||
csgInfo.glview = new OffscreenView(512,512);
|
||||
} catch (int error) {
|
||||
fprintf(stderr,"Can't create OpenGL OffscreenView. Code: %i.\n", error);
|
||||
return;
|
||||
}
|
||||
|
||||
OpenCSGRenderer opencsgRenderer(csgInfo.root_chain, csgInfo.highlights_chain, csgInfo.background_chain, csgInfo.glview->shaderinfo);
|
||||
|
||||
Vector3d center(0,0,0);
|
||||
double radius = 1.0;
|
||||
if (csgInfo.root_chain) {
|
||||
BoundingBox bbox = csgInfo.root_chain->getBoundingBox();
|
||||
center = (bbox.min() + bbox.max()) / 2;
|
||||
radius = (bbox.max() - bbox.min()).norm() / 2;
|
||||
}
|
||||
|
||||
Vector3d cameradir(1, 1, -0.5);
|
||||
Vector3d camerapos = center - radius*1.8*cameradir;
|
||||
csgInfo.glview->setCamera(camerapos, center);
|
||||
csgInfo.glview->setRenderer(&opencsgRenderer);
|
||||
OpenCSG::setContext(0);
|
||||
OpenCSG::setOption(OpenCSG::OffscreenSetting, OpenCSG::FrameBufferObject);
|
||||
csgInfo.glview->paintGL();
|
||||
csgInfo.glview->save(output);
|
||||
#else
|
||||
fprintf(stderr,"This openscad was built without OpenCSG support\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ int main(int argc, char **argv)
|
|||
desc.add_options()
|
||||
("help,h", "help message")
|
||||
("version,v", "print the version")
|
||||
("render", "if exporting an image, do a full CGAL render")
|
||||
("render", "if exporting a png image, do a full CGAL render")
|
||||
("o,o", po::value<string>(), "out-file")
|
||||
("s,s", po::value<string>(), "stl-file")
|
||||
("x,x", po::value<string>(), "dxf-file")
|
||||
|
@ -266,6 +266,7 @@ int main(int argc, char **argv)
|
|||
ModuleInstantiation root_inst;
|
||||
AbstractNode *root_node;
|
||||
AbstractNode *absolute_root_node;
|
||||
CGAL_Nef_polyhedron root_N;
|
||||
|
||||
handle_dep(filename);
|
||||
|
||||
|
@ -310,10 +311,14 @@ int main(int argc, char **argv)
|
|||
}
|
||||
else {
|
||||
#ifdef ENABLE_CGAL
|
||||
CGAL_Nef_polyhedron root_N = cgalevaluator.evaluateCGALMesh(*tree.root());
|
||||
|
||||
if (png_output_file && !vm.count("render")) {
|
||||
// OpenCSG png -> don't necessarily need CGALMesh evaluation
|
||||
} else {
|
||||
root_N = cgalevaluator.evaluateCGALMesh(*tree.root());
|
||||
}
|
||||
|
||||
fs::current_path(original_path);
|
||||
|
||||
|
||||
if (deps_output_file) {
|
||||
std::string deps_out( deps_output_file );
|
||||
std::string geom_out;
|
||||
|
@ -395,7 +400,7 @@ int main(int argc, char **argv)
|
|||
if (vm.count("render")) {
|
||||
export_png_with_cgal(&root_N, fstream);
|
||||
} else {
|
||||
export_png_with_opencsg(&root_N, fstream);
|
||||
export_png_with_opencsg(tree, fstream);
|
||||
}
|
||||
fstream.close();
|
||||
}
|
||||
|
|
|
@ -603,6 +603,8 @@ endif()
|
|||
if(EXISTS "${GUI_BINPATH}")
|
||||
add_executable(guicgalpngtest guicgalpngtest.cc)
|
||||
set_target_properties(guicgalpngtest PROPERTIES COMPILE_FLAGS "-DBINPATH=${GUI_BINPATH}")
|
||||
add_executable(guiopencsgtest guiopencsgtest.cc)
|
||||
set_target_properties(guiopencsgtest PROPERTIES COMPILE_FLAGS "-DBINPATH=${GUI_BINPATH}")
|
||||
message(STATUS "Found OpenSCAD GUI binary: ${GUI_BINPATH}")
|
||||
else()
|
||||
message(STATUS "Couldn't find the OpenSCAD GUI binary: ${GUI_BINPATH}")
|
||||
|
@ -762,6 +764,7 @@ list(APPEND THROWNTOGETHERTEST_FILES ${OPENCSGTEST_FILES})
|
|||
list(APPEND CGALSTLSANITYTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/normal-nan.scad)
|
||||
|
||||
list(APPEND GUICGALPNGTEST_FILES ${CGALPNGTEST_FILES})
|
||||
list(APPEND GUIOPENCSGTEST_FILES ${OPENCSGTEST_FILES})
|
||||
|
||||
# Disable tests which are known to cause floating point comparison issues
|
||||
# Once we're capable of comparing these across platforms, we can put these back in
|
||||
|
@ -787,10 +790,11 @@ disable_tests(dumptest_transform-tests
|
|||
# FIXME: This test illustrates a weakness in child() combined with modifiers.
|
||||
# Reenable it when this is improved
|
||||
disable_tests(opencsgtest_child-background)
|
||||
disable_tests(guiopencsgtest_child-background)
|
||||
|
||||
# FIXME: This single test takes over an hour to run on a 2.7 GHz P4
|
||||
disable_tests(opencsgtest_example006 cgalpngtest_example006)
|
||||
disable_tests(opencsgtest_example006 guicgalpngtest_example006)
|
||||
disable_tests(guiopencsgtest_example006 guicgalpngtest_example006)
|
||||
|
||||
# These tests only makes sense in OpenCSG mode
|
||||
disable_tests(cgalpngtest_child-background
|
||||
|
@ -807,6 +811,8 @@ disable_tests(cgalpngtest_child-background
|
|||
|
||||
set_test_config(Heavy opencsgtest_minkowski3-tests
|
||||
opencsgtest_projection-tests
|
||||
guiopencsgtest_minkowski3-tests
|
||||
guiopencsgtest_projection-tests
|
||||
throwntogethertest_minkowski3-tests
|
||||
throwntogethertest_projection-tests
|
||||
cgalpngtest_projection-tests
|
||||
|
@ -835,6 +841,8 @@ foreach(FILE ${EXAMPLE_FILES})
|
|||
set_test_config(Examples ${TEST_FULLNAME})
|
||||
get_test_fullname(guicgalpngtest ${FILE} TEST_FULLNAME)
|
||||
set_test_config(Examples ${TEST_FULLNAME})
|
||||
get_test_fullname(guiopencsgtest ${FILE} TEST_FULLNAME)
|
||||
set_test_config(Examples ${TEST_FULLNAME})
|
||||
endforeach()
|
||||
|
||||
# Workaround Gallium bugs
|
||||
|
@ -888,6 +896,7 @@ add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES})
|
|||
add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES})
|
||||
add_cmdline_test(throwntogethertest png ${THROWNTOGETHERTEST_FILES})
|
||||
add_cmdline_test(guicgalpngtest png ${GUICGALPNGTEST_FILES})
|
||||
add_cmdline_test(guiopencsgtest png ${GUIOPENCSGTEST_FILES})
|
||||
|
||||
# FIXME: We don't actually need to compare the output of cgalstlsanitytest
|
||||
# with anything. It's self-contained and returns != 0 on error
|
||||
|
|
|
@ -105,54 +105,6 @@ po::variables_map parse_options(int argc, char *argv[])
|
|||
return vm;
|
||||
}
|
||||
|
||||
int opencsg_prep( Tree &tree, AbstractNode *root_node, CsgInfo_OpenCSG &csgInfo )
|
||||
{
|
||||
CGALEvaluator cgalevaluator(tree);
|
||||
CSGTermEvaluator evaluator(tree, &cgalevaluator.psevaluator);
|
||||
shared_ptr<CSGTerm> root_raw_term = evaluator.evaluateCSGTerm(*root_node,
|
||||
csgInfo.highlight_terms,
|
||||
csgInfo.background_terms);
|
||||
|
||||
if (!root_raw_term) {
|
||||
cerr << "Error: CSG generation failed! (no top level object found)\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// CSG normalization
|
||||
CSGTermNormalizer normalizer(5000);
|
||||
csgInfo.root_norm_term = normalizer.normalize(root_raw_term);
|
||||
if (csgInfo.root_norm_term) {
|
||||
csgInfo.root_chain = new CSGChain();
|
||||
csgInfo.root_chain->import(csgInfo.root_norm_term);
|
||||
fprintf(stderr, "Normalized CSG tree has %d elements\n", int(csgInfo.root_chain->polysets.size()));
|
||||
}
|
||||
else {
|
||||
csgInfo.root_chain = NULL;
|
||||
fprintf(stderr, "WARNING: CSG normalization resulted in an empty tree\n");
|
||||
}
|
||||
|
||||
if (csgInfo.highlight_terms.size() > 0) {
|
||||
cerr << "Compiling highlights (" << csgInfo.highlight_terms.size() << " CSG Trees)...\n";
|
||||
|
||||
csgInfo.highlights_chain = new CSGChain();
|
||||
for (unsigned int i = 0; i < csgInfo.highlight_terms.size(); i++) {
|
||||
csgInfo.highlight_terms[i] = normalizer.normalize(csgInfo.highlight_terms[i]);
|
||||
csgInfo.highlights_chain->import(csgInfo.highlight_terms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (csgInfo.background_terms.size() > 0) {
|
||||
cerr << "Compiling background (" << csgInfo.background_terms.size() << " CSG Trees)...\n";
|
||||
|
||||
csgInfo.background_chain = new CSGChain();
|
||||
for (unsigned int i = 0; i < csgInfo.background_terms.size(); i++) {
|
||||
csgInfo.background_terms[i] = normalizer.normalize(csgInfo.background_terms[i]);
|
||||
csgInfo.background_chain->import(csgInfo.background_terms[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csgtestcore(int argc, char *argv[], test_type_e test_type)
|
||||
{
|
||||
bool sysinfo_dump = false;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// Wrapper around openscad gui binary, so it can act like a 'test'
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#ifndef BINPATH
|
||||
#error please define BINPATH=/some/path/openscad when compiling
|
||||
#endif
|
||||
#define PREQUOTE(x) #x
|
||||
#define QUOTE(x) PREQUOTE(x)
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
fprintf(stderr,"%s: wrapper for OpenSCAD at %s\n", argv[0], QUOTE( BINPATH ) );
|
||||
if ( argc != 3 ) {
|
||||
fprintf(stderr,"%s: bad number of arguments: %i\n", argv[0], argc);
|
||||
return 1;
|
||||
}
|
||||
char *newargs[6];
|
||||
char *scadfilename = argv[1];
|
||||
char *pngfilename = argv[2];
|
||||
newargs[0] = const_cast<char *>(QUOTE( BINPATH ));
|
||||
newargs[1] = scadfilename;
|
||||
newargs[2] = const_cast<char *>("-o");
|
||||
newargs[3] = pngfilename;
|
||||
newargs[4] = NULL;
|
||||
return execv( newargs[0], newargs );
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ import string
|
|||
|
||||
share_expected_imgs = {}
|
||||
share_expected_imgs["guicgalpngtest"] = "cgalpngtest"
|
||||
share_expected_imgs["guiopencsgtest"] = "opencsgtest"
|
||||
|
||||
def initialize_environment():
|
||||
if not options.generate: options.generate = bool(os.getenv("TEST_GENERATE"))
|
||||
|
|
Loading…
Reference in New Issue