Import Geant4 11.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2021-12-10 14:46:44 +01:00
committed by Ben Morgan
parent 6399a014b6
commit 80e2389dd8
3932 changed files with 202519 additions and 246221 deletions
@@ -1,75 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_GL_plots_viewer
#define tools_sg_GL_plots_viewer
// used in geant4 plotting.
#include <tools/sg/plots_viewer>
#include <tools/sg/base_freetype>
#include "GL_manager"
#include "GL_action"
namespace tools {
namespace sg {
class GL_plots_viewer : public tools::sg::plots_viewer {
TOOLS_HEADER(GL_plots_viewer,tools::sg::GL_plots_viewer,tools::sg::plots_viewer)
public:
void render() {
if(!m_ww) return;
if(!m_wh) return;
m_gl_mgr.begin_render(0,0,m_ww,m_wh,
m_clear_color.r(),
m_clear_color.g(),
m_clear_color.b(),
m_clear_color.a());
GL_action action(m_gl_mgr,m_out,m_ww,m_wh);
action.state().m_use_gsto = m_use_gsto;
m_sg.render(action);
if(!action.end()) { //check that matrices stack are ok.
m_out << "exib::sg::GL_plots_viewer :"
<< " bad gl_action end."
<< std::endl;
}
//after_render();
m_gl_mgr.end_render();
}
public:
GL_plots_viewer(std::ostream& a_out,const tools::sg::base_freetype& a_ttf,
unsigned int a_cols = 1,unsigned int a_rows = 1,
unsigned int a_width = 500,unsigned int a_height = 500)
:parent(a_out,a_ttf,a_cols,a_rows,a_width,a_height)
,m_gl_mgr(a_out)
{}
virtual ~GL_plots_viewer(){
//WARNING : nodes may refer m_gl_mgr (to handle gstos/texs), then we have to delete them first.
m_sg.clear();
m_plots.clear_sg();
}
public:
GL_plots_viewer(const GL_plots_viewer& a_from)
:parent(a_from)
,m_gl_mgr(a_from.m_gl_mgr)
{}
GL_plots_viewer& operator=(const GL_plots_viewer& a_from){
parent::operator=(a_from);
m_gl_mgr = a_from.m_gl_mgr;
return *this;
}
protected:
GL_manager m_gl_mgr;
};
}}
#endif
+12 -3
View File
@@ -28,11 +28,20 @@ public:
GL_action action(m_gl_mgr,m_out,m_ww,m_wh);
action.state().m_use_gsto = m_use_gsto;
action.set_do_transparency(false);
action.set_have_to_do_transparency(false);
m_sg.render(action);
if(!action.end()) { //check that matrices stack are ok.
m_out << "exib::sg::GL_viewer :"
<< " bad gl_action end."
<< std::endl;
m_out << "tools::sg::GL_viewer : bad gl_action end." << std::endl;
} else {
if(action.have_to_do_transparency()) {
action.set_do_transparency(true);
m_sg.render(action);
if(!action.end()) { //check that matrices stack are ok.
m_out << "tools::sg::GL_viewer : bad gl_action end." << std::endl;
}
}
}
//after_render();
+19 -8
View File
@@ -123,18 +123,18 @@ public:
if(touched()) {
if(do_back.value()) gen_back();
if(draw_edges.value()) gen_edges();
#ifdef __APPLE__
m_all_a_one = true;
{tools_vforcit_npp(float,rgbas.values(),it) {
if(*(it+3)!=1) {m_all_a_one = false;break;}
it += 4;
}}
#endif //__APPLE__
clean_gstos();
reset_touched();
}
if(xyzs.empty()) return;
if(!have_to_render(a_action)) return;
const state& state = a_action.state();
if(state.m_use_gsto) {
@@ -326,9 +326,7 @@ public:
,m_xyzs_pos(0)
,m_rgbas_pos(0)
,m_nms_pos(0)
#ifdef __APPLE__
,m_all_a_one(true)
#endif
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
@@ -351,9 +349,7 @@ public:
,m_xyzs_pos(a_from.m_xyzs_pos)
,m_rgbas_pos(a_from.m_rgbas_pos)
,m_nms_pos(a_from.m_nms_pos)
#ifdef __APPLE__
,m_all_a_one(true)
#endif
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
@@ -539,6 +535,23 @@ public:
parent::clear();
}
protected:
bool have_to_render(render_action& a_action) {
bool transparent = false;
if(rgbas.size()) {
if(!m_all_a_one) transparent = true;
} else {
if(a_action.state().m_color.a()!=1) transparent = true;
}
if(transparent) {
if(a_action.do_transparency()) return true;
a_action.set_have_to_do_transparency(true);
return false;
} else {
if(a_action.do_transparency()) return false;
}
return true;
}
void gen_back(){
m_back_xyzs.clear();
m_back_nms.clear();
@@ -688,9 +701,7 @@ protected:
size_t m_xyzs_pos;
size_t m_rgbas_pos;
size_t m_nms_pos;
#ifdef __APPLE__
bool m_all_a_one;
#endif
};
}}
+40 -4
View File
@@ -7,6 +7,7 @@
#include "base_text"
#include "gstos"
#include "sf_string"
#include <map>
// abstract class to handle freetype text.
@@ -73,6 +74,8 @@ public:
,modeling(a_from.modeling)
,unitext(a_from.unitext)
//,font_dirs(a_from.font_dirs)
,m_fonts(a_from.m_fonts)
,m_finders(a_from.m_finders)
{
add_fields();
}
@@ -85,9 +88,15 @@ public:
modeling = a_from.modeling;
unitext = a_from.unitext;
//font_dirs = a_from.font_dirs;
m_fonts = a_from.m_fonts;
m_finders = a_from.m_finders;
return *this;
}
public:
static base_freetype* create(const base_freetype& a_ttf) {
return safe_cast<node,base_freetype>(*(a_ttf.copy()));
}
public:
void dump_unitext(std::ostream& a_out) {
//unitext.values().size()
@@ -104,11 +113,38 @@ public:
a_out << "end line." << std::endl;
}
}
public:
static base_freetype* create(const base_freetype& a_ttf) {
return safe_cast<node,base_freetype>(*(a_ttf.copy()));
public:
typedef const unsigned char*(*font_getter)(unsigned int&);
void add_embedded_font(const std::string& a_name,font_getter a_getter) {
unsigned int size;
const unsigned char* buffer = a_getter(size);
m_fonts[a_name] = embedded_font(size,buffer); //warning: we do not take ownership of buffer.
}
typedef std::pair<unsigned int,const unsigned char*> embedded_font;
void add_embedded_font(const std::string& a_name,unsigned int a_size,const unsigned char* a_buffer) {
//warning: we do not take ownership of a_buffer.
m_fonts[a_name] = embedded_font(a_size,a_buffer);
}
bool find_embedded_font(const std::string& a_name,unsigned int& a_size,const unsigned char*& a_buffer) {
std::map<std::string,embedded_font>::const_iterator it = m_fonts.find(a_name);
if(it==m_fonts.end()) {a_size = 0;a_buffer = 0;return false;}
a_size = (*it).second.first;
a_buffer = (*it).second.second;
return true;
}
public:
typedef bool(*font_finder)(const std::string&,std::string&);
void add_font_finder(font_finder a_finder) {m_finders.push_back(a_finder);}
bool find_font_with_finders(const std::string& a_name,std::string& a_font) {
tools_vforcit(font_finder,m_finders,it) {
if((*it)(a_name,a_font)) return true;
}
a_font.clear();
return false;
}
protected:
std::map<std::string,embedded_font> m_fonts;
std::vector<font_finder> m_finders;
};
}}
+132
View File
@@ -0,0 +1,132 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_bcbk
#define tools_sg_bcbk
// "cbk" is for callback. Base class to handle a callback.
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include "../scast"
#include "../S_STRING"
#include <string>
namespace tools {
namespace sg {
enum return_action {
return_none,
return_to_render
};
class bcbk {
public:
TOOLS_SCLASS(tools::sg::bcbk)
public:
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<bcbk>(this,a_class)) {return p;}
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
virtual return_action action() = 0;
virtual bcbk* copy() const = 0;
//virtual bool equal(const bcbk&) const = 0; //it would need the upper cast.
public:
virtual ~bcbk(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
bcbk()
:m_single_shoot(false)
,m_is_valid(true)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
bcbk(const bcbk& a_from)
:m_single_shoot(a_from.m_single_shoot)
,m_is_valid(a_from.m_is_valid)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
bcbk& operator=(const bcbk& a_from){
m_single_shoot = a_from.m_single_shoot;
m_is_valid = a_from.m_is_valid;
return *this;
}
public:
void set_single_shoot(bool a_value) {m_single_shoot = a_value;}
bool is_single_shoot() const {return m_single_shoot;}
bool is_valid() const {return m_is_valid;}
void invalidate() {m_is_valid = false;}
protected:
bool m_single_shoot;
bool m_is_valid;
};
}}
#define TOOLS_CBK(a__class,a__sclass,a__parent)\
private:\
typedef a__parent parent;\
public:\
TOOLS_SCLASS(a__sclass)\
public:\
virtual void* cast(const std::string& a_class) const {\
if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
return parent::cast(a_class);\
}\
virtual const std::string& s_cls() const {return s_class();}\
virtual tools::sg::bcbk* copy() const {return new a__class(*this);}
#define TOOLS_T_CBK(a__T,a__class,a__sclass,a__parent)\
private:\
typedef a__parent parent;\
public:\
TOOLS_T_SCLASS(a__T,a__sclass)\
public:\
virtual void* cast(const std::string& a_class) const {\
if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
return parent::cast(a_class);\
}\
virtual const std::string& s_cls() const {return s_class();}\
virtual tools::sg::bcbk* copy() const {return new a__class(*this);}
#define TOOLS_T2_CBK(a__T1,a__T2,a__class,a__sclass,a__parent)\
private:\
typedef a__parent parent;\
public:\
TOOLS_T2_SCLASS(a__T1,a__T2,a__sclass)\
public:\
virtual void* cast(const std::string& a_class) const {\
if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
return parent::cast(a_class);\
}\
virtual const std::string& s_cls() const {return s_class();}\
virtual tools::sg::bcbk* copy() const {return new a__class(*this);}
#define TOOLS_T3_CBK(a__T1,a__T2,a__T3,a__class,a__sclass,a__parent)\
private:\
typedef a__parent parent;\
public:\
TOOLS_T3_SCLASS(a__T1,a__T2,a__T3,a__sclass)\
public:\
virtual void* cast(const std::string& a_class) const {\
if(void* p = tools::cmp_cast<a__class>(this,a_class)) return p;\
return parent::cast(a_class);\
}\
virtual const std::string& s_cls() const {return s_class();}\
virtual tools::sg::bcbk* copy() const {return new a__class(*this);}
#endif
+57
View File
@@ -0,0 +1,57 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_cbks
#define tools_sg_cbks
// A dedicated container for callbacks.
#include "bcbk"
#include "../forit"
#include "../vmanip"
#include <vector>
namespace tools {
namespace sg {
class cbks {
public:
cbks() {}
virtual ~cbks(){clear();}
public:
cbks(const cbks& a_from){copy(a_from);}
cbks& operator=(const cbks& a_from){
if(&a_from==this) return *this;
copy(a_from);
return *this;
}
public:
void add(bcbk* a_cbk) {
//we take ownership of a_cbk
m_cbks.push_back(a_cbk);
}
void copy(const cbks& a_from,bool a_clear = true) {
if(&a_from==this) return;
if(a_clear) clear();
tools_vforcit(bcbk*,a_from.m_cbks,it) m_cbks.push_back((*it)->copy());
}
void clear() {
safe_clear<bcbk>(m_cbks);
}
void do_actions() const {
// WARNING : dangerous. Used by offscreen apps.
tools_vforcit(bcbk*,m_cbks,it) (*it)->action();
}
const std::vector<bcbk*>& callbacks() const {return m_cbks;}
std::vector<bcbk*>& callbacks() {return m_cbks;}
bool is_empty() const {return m_cbks.empty();}
protected:
std::vector<bcbk*> m_cbks;
};
}}
#endif
-86
View File
@@ -1,86 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_color
#define tools_sg_color
#include "node"
#include "sf_vec"
#include "render_action"
#include "../colorf"
namespace tools {
namespace sg {
class color : public node {
TOOLS_NODE(color,tools::sg::color,node)
public:
sf_vec<colorf,float> rgb;
sf<float> transparency; //alpha=1-transparency. Opaque is transparency=0.
public:
virtual const desc_fields& node_desc_fields() const {
TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::color)
static const desc_fields s_v(parent::node_desc_fields(),2, //WARNING : take care of count.
TOOLS_ARG_FIELD_DESC(rgb),
TOOLS_ARG_FIELD_DESC(transparency)
);
return s_v;
}
private:
void add_fields(){
add_field(&rgb);
add_field(&transparency);
}
public:
virtual void render(render_action& a_action) {
// GL-ES : ::glMaterialfv does not work. We then use :
// ::glEnable(GL_COLOR_MATERIAL) and ::glColor.
//if(a_action.state().m_GL_LIGHTING) {
// float params[4];
// params[0] = rgb.value().r();
// params[1] = rgb.value().g();
// params[2] = rgb.value().b();
// params[3] = 1-transparency.value();
// ::glMaterialfv(GL_FRONT,GL_DIFFUSE,params);
//} else {
//}
state& state = a_action.state();
state.m_color[0] = rgb.value().r();
state.m_color[1] = rgb.value().g();
state.m_color[2] = rgb.value().b();
state.m_color[3] = 1-transparency.value();
a_action.color4f(state.m_color);
}
public:
color()
:parent()
,rgb(colorf_default())
,transparency(0.0f)
{
add_fields();
}
virtual ~color(){}
public:
color(const color& a_from)
:parent(a_from)
,rgb(a_from.rgb)
,transparency(a_from.transparency)
{
add_fields();
}
color& operator=(const color& a_from){
parent::operator=(a_from);
rgb = a_from.rgb;
transparency = a_from.transparency;
return *this;
}
};
}}
#endif
+118
View File
@@ -0,0 +1,118 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_ecbk
#define tools_sg_ecbk
// A callback class to handle a response to some event
// (viewer/window size, mouse button press, etc...).
// It is typically used through the event_dispatcher node.
#include "bcbk"
#include "event"
#include "event_action"
#include "../forit"
#include "../HEADER"
#include <vector>
namespace tools {
namespace sg {
class node;
}}
namespace tools {
namespace sg {
class ecbk : public bcbk {
TOOLS_HEADER(ecbk,tools::sg::ecbk,bcbk)
public:
ecbk(unsigned int a_action = 0)
:parent()
,m_action(a_action)
,m_no_set_done(false)
,m_event(0)
,m_event_action(0)
,m_node(0)
,m_z(0)
,m_w(0)
{}
virtual ~ecbk(){delete m_event;}
public:
ecbk(const ecbk& a_from)
:parent(a_from)
,m_action(a_from.m_action)
,m_no_set_done(a_from.m_no_set_done)
,m_event(0)
,m_event_action(a_from.m_event_action)
,m_node(a_from.m_node)
,m_z(a_from.m_z)
,m_w(a_from.m_w)
{
if(a_from.m_event) m_event = a_from.m_event->copy();
}
ecbk& operator=(const ecbk& a_from){
parent::operator=(a_from);
m_action = a_from.m_action;
m_no_set_done = a_from.m_no_set_done;
delete m_event;
m_event = 0;
if(a_from.m_event) m_event = a_from.m_event->copy();
m_event_action = a_from.m_event_action;
m_node = a_from.m_node;
m_z = a_from.m_z;
m_w = a_from.m_w;
return *this;
}
public:
void set_action(unsigned int a_v){m_action = a_v;}
void set_no_set_done(bool a_v) {m_no_set_done = a_v;}
// for ArcheryTune :
event& event_ref() const {return *m_event;}
event_action& event_action_ref() const {return *m_event_action;}
public:
static void exec_event_cbks(const std::vector<bcbk*>& a_cbks,
const event& a_evt,
event_action* a_action,
node* a_node,
float a_z = 0,float a_w = 0) {
tools_vforcit(bcbk*,a_cbks,it) {
bcbk* _cbk = (*it)->copy();
if(ecbk* _ecbk = safe_cast<bcbk,ecbk>(*_cbk)){
delete _ecbk->m_event;
_ecbk->m_event = a_evt.copy();
_ecbk->m_event_action = a_action;
_ecbk->m_node = a_node;
_ecbk->m_z = a_z;
_ecbk->m_w = a_w;
_ecbk->action();
if(a_action->done()) {
delete _cbk;
break;
}
}
delete _cbk;
}
}
public:
unsigned int m_action;
bool m_no_set_done; //to tell not doing m_event_action->set_done(true).
event* m_event; //owner
event_action* m_event_action; //not owner.
node* m_node; //not owner.
float m_z;
float m_w;
};
}}
#endif
@@ -0,0 +1,48 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_event_dispatcher
#define tools_sg_event_dispatcher
// Node that holds "callbacks" that can be triggered when an event_action
// traversed it. A typical example is to handle a mouse resize of the viewer/window
// and response to it by changing some geomtry in the scene graphs (for example
// to arrange that a tools::sg::plots maps the full viewer/window area).
#include "node"
#include "cbks"
#include "event_action"
#include "ecbk"
namespace tools {
namespace sg {
class event_dispatcher : public node {
TOOLS_NODE(event_dispatcher,tools::sg::event_dispatcher,node)
public:
virtual void event(event_action& a_action) {
ecbk::exec_event_cbks(m_cbks.callbacks(),a_action.get_event(),&a_action,this);
}
public:
event_dispatcher():parent(),m_cbks(){}
virtual ~event_dispatcher(){}
public:
event_dispatcher(const event_dispatcher& a_from):parent(a_from),m_cbks(a_from.m_cbks){}
event_dispatcher& operator=(const event_dispatcher& a_from){
parent::operator=(a_from);
m_cbks = a_from.m_cbks;
return *this;
}
public:
const sg::cbks& cbks() const {return m_cbks;}
//sg::cbks& cbks() {return m_cbks;}
void add_callback(bcbk* a_cbk) {m_cbks.add(a_cbk);} //we take ownership of a_cbk
void copy_cbks(const sg::cbks& a_from,bool a_clear = true) {m_cbks.copy(a_from,a_clear);}
void clear_cbks(){m_cbks.clear();}
protected:
sg::cbks m_cbks;
};
}}
#endif
@@ -648,6 +648,7 @@ inline bool s2format(const std::string& a_format,int& a_gl2ps_format) {
if(a_format=="gl2ps_svg") {a_gl2ps_format = TOOLS_GL2PS_SVG;return true;}
if(a_format=="gl2ps_tex") {a_gl2ps_format = TOOLS_GL2PS_TEX;return true;}
if(a_format=="gl2ps_pgf") {a_gl2ps_format = TOOLS_GL2PS_PGF;return true;}
a_gl2ps_format = TOOLS_GL2PS_PS;
return false;
}
+36
View File
@@ -0,0 +1,36 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_light_off
#define tools_sg_light_off
// A node to cancel/switch of the lighting during a render traversal.
#include "node"
#include "render_action"
namespace tools {
namespace sg {
class light_off : public node {
TOOLS_NODE(light_off,tools::sg::light_off,node)
public:
virtual void render(render_action& a_action) {
state& state = a_action.state();
state.m_GL_LIGHTING = false;
a_action.set_lighting(false);
}
public:
light_off():parent() {}
virtual ~light_off(){}
public:
light_off(const light_off& a_from):parent(a_from){}
light_off& operator=(const light_off& a_from){
parent::operator=(a_from);
return *this;
}
};
}}
#endif
-114
View File
@@ -1,114 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_line_set
#define tools_sg_line_set
#include "node"
#include "mf"
#include "../stype"
#include "render_action"
#include "pick_action"
#include "bbox_action"
namespace tools {
namespace sg {
class line_set : public node {
TOOLS_NODE(line_set,tools::sg::line_set,node)
public:
mf_std_vec<float> lines;
public:
virtual const desc_fields& node_desc_fields() const {
TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::line_set)
static const desc_fields s_v(parent::node_desc_fields(),1, //WARNING : take care of count.
TOOLS_ARG_FIELD_DESC(lines)
);
return s_v;
}
private:
void add_fields(){
add_field(&lines);
}
public:
typedef std::vector<float> line_t;
virtual void render(render_action& a_action) {
tools_vforcit(line_t,lines.values(),it) {
a_action.draw_vertex_array(gl::line_strip(),*it);
}
}
virtual void pick(pick_action& a_action) {
if(a_action.stop_at_first()){
tools_vforcit(line_t,lines.values(),it) {
a_action.add_line_strip(*it);
if(a_action.done()) {
a_action.set_node(this);
return;
}
}
} else {
tools_vforcit(line_t,lines.values(),it) {
a_action.set_done(false);
a_action.zs().clear();
a_action.ws().clear();
a_action.add_line_strip(*it);
if(a_action.done()) {
a_action.add_pick(*this,a_action.zs(),a_action.ws(),a_action.state());
a_action.set_done(false);
}
}
}
}
virtual void bbox(bbox_action& a_action) {
tools_vforcit(line_t,lines.values(),it) {
a_action.add_points(*it);
}
}
public:
line_set()
:parent()
,lines()
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
add_fields();
}
virtual ~line_set(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
line_set(const line_set& a_from)
:parent(a_from)
,lines(a_from.lines)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
add_fields();
}
line_set& operator=(const line_set& a_from){
parent::operator=(a_from);
lines = a_from.lines;
return *this;
}
public:
bool add(const line_t& a_line) {
size_t npoint = a_line.size()/3;
if(npoint*3!=a_line.size()) return false;
lines.add(a_line);
return true;
}
void clear() {lines.clear();}
};
}}
#endif
+169
View File
@@ -0,0 +1,169 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
//
// Helper functions to handle node(s) paths in a scene graph.
//
#ifndef tools_sg_path
#define tools_sg_path
#include "node"
#include "noderef"
#include "../pointer"
namespace tools {
namespace sg {
typedef std::vector<node*> path_t;
inline bool parent_class(const path_t& a_path,std::string& a_class) {
if(a_path.size()<2) {a_class.clear();return false;}
node* parent = a_path[a_path.size()-2];
a_class = parent->s_cls();
return true;
}
template <class NODE>
inline NODE* rfind(const path_t& a_path) {
path_t::const_reverse_iterator it;
for(it=a_path.rbegin();it!=a_path.rend();++it){
if(NODE* par = safe_cast<node,NODE>(*(*it))) return par;
}
return 0;
}
template <class NODE>
inline NODE* tail(const path_t& a_path) {
if(a_path.empty()) return 0;
node* _node = a_path[a_path.size()-1];
return safe_cast<node,NODE>(*_node);
}
inline bool remove_tail(path_t& a_path) {
if(a_path.empty()) return false;
a_path.resize(a_path.size()-1);
return true;
}
template <class CONTAINER>
inline CONTAINER* container(const path_t& a_path) {
if(a_path.size()<2) return 0;
node* parent = a_path[a_path.size()-2];
return safe_cast<node,CONTAINER>(*parent);
}
template <class CONTAINER>
inline CONTAINER* container_container(const path_t& a_path) {
if(a_path.size()<3) return 0;
node* parent = a_path[a_path.size()-3];
return safe_cast<node,CONTAINER>(*parent);
}
inline void dump(std::ostream& a_out,const path_t& a_path) {
a_out << "tools::sg::dump : path size " << a_path.size() << std::endl;
std::string s;
path_t::const_iterator it;
for(it=a_path.begin();it!=a_path.end();++it){
if(!p2s(*it,s)) {}
a_out << " " << s << " " << (*it)->s_cls();
if(noderef* _ref = safe_cast<node,noderef>(*(*it))) {
if(!p2s(&(_ref->node()),s)) {}
a_out << ", " << s << " " << _ref->node().s_cls();
}
a_out << std::endl;
}
}
//#define TOOLS_RFIND_DEBUG
template <class WHAT,class CONTAINER>
inline bool rfind(const path_t& a_path,const node& a_from,
CONTAINER*& a_container,WHAT*& a_what,
int& a_container_index){
node* from = (node*)&a_from;
path_t::size_type sz = a_path.size();
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : from %s, a_path.size() %d\n",a_from.s_cls().c_str(),sz);
//::printf("debug : rfind : search node of class %s\n",typename WHAT::s_cls().c_str());
#endif
for(size_t index=1;index<sz;index++) {
node* _node = a_path[sz-index-1];
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : index %d, node %s\n",index,_node->s_cls().c_str());
#endif
a_container = safe_cast<node,CONTAINER>(*_node);
if(a_container) {
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : node is a container of size %d\n",a_container->size());
#endif
//the below does not compile.
//a_what = a_container->rsearch_from<WHAT>(from);
//if(a_what) return true;
void* p = a_container->rsearch_from(from,WHAT::s_class(),false);
if(p) {
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : found in container %lu\n",p);
#endif
a_what = (WHAT*)p;
a_container_index = int(sz-index-1);
return true;
}
from = a_container;
} else if(noderef* _ref = safe_cast<node,noderef>(*_node)) {
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : node is a noderef with a %s\n",_ref->node().s_cls().c_str());
#endif
from = _ref;
} else { // weird case :
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : weird case\n");
#endif
break;
}
}
#ifdef TOOLS_RFIND_DEBUG
::printf("debug : rfind : failed\n");
#endif
a_what = 0;
a_container = 0;
a_container_index = -1;
return false;
}
#ifdef TOOLS_RFIND_DEBUG
#undef TOOLS_RFIND_DEBUG
#endif
template <class WHAT,class CONTAINER>
inline bool find_top(const path_t& a_path,const node& a_from,
CONTAINER*& a_container,WHAT*& a_what,
int& a_container_index){
a_what = 0;
a_container = 0;
a_container_index = -1;
path_t _path = a_path;
node* from = (node*)&a_from;
while(true) {
CONTAINER* container;
WHAT* what;
int idx; //index in path of container.
if(!sg::rfind<WHAT,CONTAINER>(_path,*from,container,what,idx)) {
break;
}
a_container = container;
a_what = what;
a_container_index = idx;
_path.resize(idx+1);
_path.push_back(what);
from = what;
}
return a_container?true:false;
}
typedef std::vector<path_t> paths_t;
}}
#endif
@@ -0,0 +1,360 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_plotter_some_styles
#define tools_sg_plotter_some_styles
// Functions to set some common styles.
// Typically ROOT_default (the default style of ROOT), hippodraw
// or return/reset to the default inlib style.
#include "plotter"
#include "style_colormap"
namespace tools {
namespace sg {
inline bool set_style_color(std::ostream& a_out,const cmaps_t& a_cmaps,const std::string& a_s,colorf& a_col){
if(!find_color(a_cmaps,a_s,a_col)) {
a_out << "tools::sg::set_style_color: color " << sout(a_s) << " not found." << std::endl;
return false;
}
return true;
}
// a_font = font_arialbd_ttf(); //idem ROOT 62.
// a_font = font_roboto_bold_ttf(); //open source replacement for arialbd.
inline void set_style_font(text_style& a_style,const std::string& a_font){
a_style.font = a_font;
a_style.front_face = winding_cw;
a_style.smoothing = true;
}
inline void set_ROOT_default_style(std::ostream& a_out,const cmaps_t& a_cmaps,plotter& a_plotter,const std::string& a_font) {
a_plotter.value_top_margin = 0.05f;
a_plotter.bottom_margin = 0.1f;
a_plotter.top_margin = 0.1f;
a_plotter.left_margin = 0.1f;
a_plotter.right_margin = 0.1f;
{style& _style = a_plotter.background_style();
_style.visible = true;
//if(!set_style_color(a_out,a_cmaps,"ROOT/grey19",_style.back_color.value())) {}
//border:
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.line_width = 0.003; // 0 = no border. In % of width.
}
// <!-- <style name="wall_style"><visible>false</visible></style> -->
{style& _style = a_plotter.grid_style();
_style.visible = false;
//if(!set_style_color(a_out,a_cmaps,"white",_style.color.value())) {}
}
// plot title done with the title_box (and not plotter title):
{text_style& _style = a_plotter.title_style();
_style.visible = false;
}
{text_style& _style = a_plotter.title_box_style();
_style.visible = true;
if(!set_style_color(a_out,a_cmaps,"ROOT/grey19",_style.back_color.value())) {}
_style.back_shadow = 0.015f; //% of width.
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
set_style_font(_style,a_font);}
a_plotter.infos_width = 0.35f;
a_plotter.infos_x_margin = 0.01f; //from right border.
a_plotter.infos_y_margin = 0.005f; //from top border.
{text_style& _style = a_plotter.infos_style();
_style.visible = true;
if(!set_style_color(a_out,a_cmaps,"ROOT/grey19",_style.back_color.value())) {}
_style.back_shadow = 0.015f; //% of width.
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.modeling = infos_modeling_ROOT(); //to have histo name as info title.
set_style_font(_style,a_font);}
{style& _style = a_plotter.inner_frame_style();
_style.visible = true;
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.line_width = 1.0f;
//_style.line_pattern = line_solid;
}
//////////////////////////////////////////////////////////
/// x axis: //////////////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.x_axis();
_axis.modeling = tick_modeling_hplot();
_axis.divisions = 510;
_axis.title_hjust = right;
_axis.label_to_axis = 0.005f;
_axis.label_height = 0.04f;
_axis.tick_length = 0.03f;
_axis.title_to_axis = 0.05f; //YLAB = 0.05
_axis.title_height = 0.04f;
_axis.is_log = false;
{line_style& _style = _axis.line_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{line_style& _style = _axis.ticks_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
{text_style& _style = _axis.title_style();
_style.visible = true;
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
{text_style& _style = _axis.mag_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
}
//////////////////////////////////////////////////////////
/// y axis: //////////////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.y_axis();
_axis.modeling = tick_modeling_hplot();
_axis.divisions = 510;
_axis.title_hjust = right;
_axis.label_to_axis = 0.005f;
_axis.label_height = 0.04f;
_axis.tick_length = 0.03f;
_axis.title_to_axis = 0.07f; //XLAB = 0.07
_axis.title_height = 0.04f;
_axis.is_log = false;
{line_style& _style = _axis.line_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{line_style& _style = _axis.ticks_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6;
set_style_font(_style,a_font);}
{text_style& _style = _axis.title_style();
_style.visible = true;
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
{text_style& _style = _axis.mag_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
}
//////////////////////////////////////////////////////////
/// z axis: //////////////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.z_axis();
_axis.modeling = tick_modeling_hplot();
_axis.is_log = false;
{line_style& _style = _axis.line_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{line_style& _style = _axis.ticks_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6;}
{text_style& _style = _axis.title_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6;}
{text_style& _style = _axis.mag_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6;}
}
//////////////////////////////////////////////////////////
/// colormap axis: ///////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.colormap_axis();
_axis.modeling = tick_modeling_hplot();
_axis.divisions = 510;
_axis.title_hjust = right;
_axis.label_to_axis = 0.005f;
_axis.label_height = 0.04f;
_axis.tick_length = 0.03f;
_axis.title_to_axis = 0.07f; //XLAB = 0.07
_axis.title_height = 0.04f;
_axis.is_log = false;
{line_style& _style = _axis.line_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{line_style& _style = _axis.ticks_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.width = 1.0f;}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
{text_style& _style = _axis.title_style();
_style.visible = true;
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
{text_style& _style = _axis.mag_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.scale = 0.6; //To have a good matching with ROOT text size.
set_style_font(_style,a_font);}
}
{style& _style = a_plotter.bins_style(0);
_style.modeling = modeling_top_lines();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.line_width = 1.0f;
//_style.line_pattern = line_solid;
}
{style& _style = a_plotter.func_style(0);
_style.modeling = modeling_top_lines();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.line_width = 3.0f;
//_style.line_pattern = line_solid;
}
}
// a_font = font_helvetica_ttf();
// a_font = font_lato_regular_ttf(); //open source replacement for helvetica
inline void set_hippodraw_style(std::ostream& a_out,const cmaps_t& a_cmaps,plotter& a_plotter,const std::string& a_font) {
// In memory of P.Kunz.
a_plotter.value_top_margin = 0.05f;
a_plotter.bottom_margin = 0.12f;
a_plotter.top_margin = 0.16f;
a_plotter.left_margin = 0.16f;
a_plotter.right_margin = 0.16f;
a_plotter.title_to_axis = 0.1f;
a_plotter.title_height = 0.03f;
// <!-- <style name="wall_style"><visible>false</visible></style> -->
{style& _style = a_plotter.grid_style();
_style.visible = false;}
{style& _style = a_plotter.inner_frame_style();
_style.visible = true;}
{text_style& _style = a_plotter.infos_style();
_style.visible = false;}
{text_style& _style = a_plotter.title_style();
set_style_font(_style,a_font);
_style.visible = true;}
//////////////////////////////////////////////////////////
/// x axis: //////////////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.x_axis();
_axis.modeling = tick_modeling_hippo();
_axis.title_hjust = center;
_axis.label_to_axis = 0.015f;
_axis.title_to_axis = 0.07f;
_axis.title_height = 0.035f;
_axis.label_height = 0.02625f; //0.0175F * 1.5F
{text_style& _style = _axis.title_style();
_style.visible = true;
set_style_font(_style,a_font);}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
set_style_font(_style,a_font);}
}
//////////////////////////////////////////////////////////
/// y axis: //////////////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.y_axis();
_axis.modeling = tick_modeling_hippo();
_axis.title_hjust = center;
_axis.title_to_axis = 0.2f;
_axis.title_height = 0.035f;
_axis.label_height = 0.02625f; //0.0175F * 1.5F
{text_style& _style = _axis.title_style();
_style.visible = true;
set_style_font(_style,a_font);}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
set_style_font(_style,a_font);}
}
//////////////////////////////////////////////////////////
/// z axis: //////////////////////////////////////////////
//////////////////////////////////////////////////////////
{axis& _axis = a_plotter.z_axis();
{text_style& _style = _axis.title_style();
_style.visible = true;
set_style_font(_style,a_font);}
{text_style& _style = _axis.labels_style();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
set_style_font(_style,a_font);}
}
{style& _style = a_plotter.bins_style(0);
_style.modeling = modeling_top_lines();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.line_width = 1.0f;
//_style.line_pattern = line_solid;
}
{style& _style = a_plotter.func_style(0);
_style.modeling = modeling_top_lines();
if(!set_style_color(a_out,a_cmaps,"black",_style.color.value())) {}
_style.line_width = 1.0f;
//_style.line_pattern = line_solid;
}
{style& _style = a_plotter.errors_style(0);
_style.visible = false;
}
}
inline void set_inlib_default_style(std::ostream&,const cmaps_t&,plotter& a_plotter,const std::string&) {
{axis& _axis = a_plotter.colormap_axis();
_axis.label_to_axis = 0.01f;}
}
}}
#endif
-499
View File
@@ -1,499 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_polyhedron
#define tools_sg_polyhedron
#include "node"
#include "sf"
#include "render_action"
#include "pick_action"
#include "bbox_action"
#include "state"
#include "render_manager"
#include "gstos"
#include "../hep/sf_polyhedron"
#include "../vmanip"
#include "tessellate"
namespace tools {
namespace sg {
class polyhedron : public node, public gstos {
TOOLS_NODE(polyhedron,tools::sg::polyhedron,node)
public:
hep::sf_polyhedron ph;
sf<bool> solid;
sf<bool> reduced_wire_frame;
sf<bool> enforce_edges;
public:
virtual const desc_fields& node_desc_fields() const {
TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::polyhedron)
static const desc_fields s_v(parent::node_desc_fields(),4, //WARNING : take care of count.
TOOLS_ARG_FIELD_DESC(ph),
TOOLS_ARG_FIELD_DESC(solid),
TOOLS_ARG_FIELD_DESC(reduced_wire_frame),
TOOLS_ARG_FIELD_DESC(enforce_edges)
);
return s_v;
}
private:
void add_fields(){
add_field(&ph);
add_field(&solid);
add_field(&reduced_wire_frame);
add_field(&enforce_edges);
}
public: //node
typedef tessellate::prims_t prims_t;
protected: //gstos
virtual unsigned int create_gsto(std::ostream& a_out,render_manager& a_mgr) {
m_size = 0;
if(solid.value()) {
size_t sz = 0;
if(m_draw_edges) sz += m_xyzs.size();
{tools_vforcit(prims_t,m_primss,itt) {
const prims_t& prims = *itt;
tools_vforcit(tess_prim*,prims,it) {
const tess_prim& item = *(*it);
const std::vector<float>& coords = item.m_coords;
const std::vector<float>& norms = item.m_norms;
if(coords.empty()) continue;
if(norms.size()!=coords.size()) {
a_out << "tools::sg::polyhedron::create_gsto :"
<< " bad number of normals."
<< std::endl;
continue;
}
sz += coords.size()+norms.size();
}
}}
if(sz) {
float* buffer = new float[sz];
char* pos = (char*)buffer;
size_t psz = 0;
if(m_draw_edges) {
if(m_xyzs.size()) {
size_t _sz = m_xyzs.size()*sizeof(float);
::memcpy(pos,vec_data<float>(m_xyzs),_sz);
pos += _sz;
psz += _sz;
m_size = m_xyzs.size();
//m_xyzs.clear(); //we need them for pick,write,...
}
}
{tools_vforcit(prims_t,m_primss,itt) {
const prims_t& prims = *itt;
tools_vforcit(tess_prim*,prims,it) {
tess_prim& item = *(*it);
const std::vector<float>& coords = item.m_coords;
const std::vector<float>& norms = item.m_norms;
if(coords.empty()) continue;
if(norms.size()!=coords.size()) continue;
item.m_size = coords.size();
{item.m_pos_coords = psz;
size_t _sz = coords.size()*sizeof(float);
::memcpy(pos,vec_data<float>(coords),_sz);
pos += _sz;
psz += _sz;}
{item.m_pos_norms = psz;
size_t _sz = norms.size()*sizeof(float);
::memcpy(pos,vec_data<float>(norms),_sz);
pos += _sz;
psz += _sz;}
// we don't need coords, norms for rendering
// but needed for pick,write...
//coords.clear();
//norms.clear();
//we still need m_prims.
}
}}
unsigned int id = a_mgr.create_gsto_from_data(sz,buffer);
delete [] buffer;
return id;
}
} else {
m_size = m_xyzs.size();
return a_mgr.create_gsto_from_data(m_xyzs);
}
return 0;
}
public:
virtual void render(render_action& a_action) {
const state& state = a_action.state();
bool draw_edges = false;
if(solid.value()) {
draw_edges = state.m_GL_LIGHTING?false:true;
if(enforce_edges.value()) draw_edges = true;
}
if( touched() ||
(draw_edges && m_xyzs.empty()) ||
(solid.value() && m_primss.empty()) ){
update_what what = lines;
if(solid.value()) what = draw_edges?faces_and_lines:faces;
update_sg(a_action.out(),what);
reset_touched();
}
unsigned int _id = 0;
if(state.m_use_gsto) {
m_draw_edges = draw_edges;
_id = get_gsto_id(a_action.out(),a_action.render_manager());
} else {
clean_gstos(&a_action.render_manager());
}
//a_action.out() << "debug : tools::sg::polyhedron::render_action :"
// << " m_xyzs.size() " << m_xyzs.size()
// << " m_primss.size() " << m_primss.size()
// << std::endl;
if(solid.value()) {
if(_id) {
a_action.begin_gsto(_id);
if(draw_edges && m_size) {
//Same logic as Inventor SoLightModel.model = BASE_COLOR.
a_action.set_lighting(false);
a_action.color4f(0,0,0,1);
a_action.draw_gsto_v(gl::lines(),m_size/3,0);
//pushes back the filled polygons to avoid z-fighting with lines
a_action.set_polygon_offset(true);
a_action.color4f(state.m_color);
a_action.set_lighting(state.m_GL_LIGHTING);
}
{tools_vforcit(prims_t,m_primss,itt) {
const prims_t& prims = *itt;
tools_vforcit(tess_prim*,prims,it) {
const tess_prim& item = *(*it);
a_action.draw_gsto_vn(item.m_mode,item.m_size/3,item.m_pos_coords,item.m_pos_norms);
}
}}
a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL);
a_action.end_gsto();
} else {
if(draw_edges){
if(m_xyzs.size()) {
//Same logic as Inventor SoLightModel.model = BASE_COLOR.
a_action.set_lighting(false);
a_action.color4f(0,0,0,1);
a_action.draw_vertex_array(gl::lines(),m_xyzs);
//pushes back the filled polygons to avoid z-fighting with lines
a_action.set_polygon_offset(true);
a_action.color4f(state.m_color);
a_action.set_lighting(state.m_GL_LIGHTING);
}
}
{tools_vforcit(prims_t,m_primss,itt) {
const prims_t& prims = *itt;
tools_vforcit(tess_prim*,prims,it) {
const tess_prim& item = *(*it);
const std::vector<float>& coords = item.m_coords;
if(coords.empty()) continue;
const std::vector<float>& norms = item.m_norms;
if(norms.size()!=coords.size()) {
a_action.out() << "tools::sg::polyhedron::render :"
<< " bad number of normals."
<< std::endl;
continue;
}
a_action.draw_vertex_normal_array(item.m_mode,coords,norms);
}
}}
a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL);
}
} else { //not solid
//Same logic as Inventor SoLightModel.model = BASE_COLOR.
a_action.set_lighting(false); // do we want that ?
if(_id) {
a_action.begin_gsto(_id);
a_action.draw_gsto_v(gl::lines(),m_size/3,0);
a_action.end_gsto();
} else {
a_action.draw_vertex_array(gl::lines(),m_xyzs);
}
a_action.set_lighting(state.m_GL_LIGHTING);
}
}
virtual void bbox(bbox_action& a_action) {
if(touched()) {
update_sg(a_action.out(),lines);
reset_touched();
}
if(solid.value()) {
tools_vforcit(prims_t,m_primss,itt) {
const prims_t& prims = *itt;
tools_vforcit(tess_prim*,prims,it) {
const tess_prim& item = *(*it);
const std::vector<float>& coords = item.m_coords;
a_action.add_points(coords);
}
}
} else {
a_action.add_points(m_xyzs);
}
}
virtual void pick(pick_action& a_action) {
if(touched()) {
update_what what = solid.value()?faces:lines;
update_sg(a_action.out(),what);
reset_touched();
}
if(solid.value()) {
tools_vforcit(prims_t,m_primss,itt) {
const prims_t& prims = *itt;
tools_vforcit(tess_prim*,prims,it) {
const tess_prim& item = *(*it);
const std::vector<float>& coords = item.m_coords;
if(a_action.add__primitive(*this,item.m_mode,coords,true)) return;
}
}
} else {
a_action.add__lines(*this,m_xyzs,true);
}
}
public:
polyhedron()
:parent()
,ph(hep::polyhedron())
,solid(true)
,reduced_wire_frame(true)
,enforce_edges(false)
,m_tess(0)
{
add_fields();
}
virtual ~polyhedron(){
_clear();
delete m_tess;
}
public:
polyhedron(const polyhedron& a_from)
:parent(a_from)
,gstos(a_from)
,ph(a_from.ph)
,solid(a_from.solid)
,reduced_wire_frame(a_from.reduced_wire_frame)
,enforce_edges(a_from.enforce_edges)
,m_xyzs(a_from.m_xyzs)
,m_tess(0)
{
add_fields();
}
polyhedron& operator=(const polyhedron& a_from){
parent::operator=(a_from);
gstos::operator=(a_from);
ph = a_from.ph;
solid = a_from.solid;
reduced_wire_frame = a_from.reduced_wire_frame;
enforce_edges = a_from.enforce_edges;
m_xyzs = a_from.m_xyzs;
return *this;
}
public:
enum update_what {
faces = 0,
lines = 1,
faces_and_lines
};
void update_sg(std::ostream& a_out,const update_what& a_what) {
//a_out << "debug : tools::sg::polyhedron::update_sg" << std::endl;
clean_gstos(); //must reset for all render_manager.
_clear();
const hep::polyhedron& sbPolyhedron = ph.value();
if(sbPolyhedron.GetNoFacets()<=0) {
//a_out << "tools::sg::polyhedron::update_sg : abnormal polyhedron." << std::endl;
return; // Abnormal polyhedron.
}
if((a_what==faces)||(a_what==faces_and_lines)) {
std::vector<double> doubles;
vec3d unitNormal;
vec3d* pV = sbPolyhedron.GetPV();
// Assume all facets are convex quadrilaterals :
bool notLastFace;
do {
notLastFace = sbPolyhedron.GetNextUnitNormal(unitNormal);
doubles.clear(); //begin POLYGON
bool notLastEdge;
int edgeFlag = 1;
do {
// optimize to avoid copying vec3f.
//notLastEdge = sbPolyhedron.GetNextVertex(vertex,edgeFlag);
int index;
notLastEdge = sbPolyhedron.GetNextVertexIndex(index,edgeFlag);
vec3d* vertex = pV+index; //WARNING : must not be modified !
doubles.push_back((*vertex)[0]);
doubles.push_back((*vertex)[1]);
doubles.push_back((*vertex)[2]);
} while (notLastEdge);
if(!m_tess) m_tess = new tessellate(a_out);
m_primss.push_back(prims_t());
prims_t& prims = m_primss.back();
m_tess->do_it(doubles.size()/3,vec_data(doubles),prims);
m_tess->clear();
} while (notLastFace);
}
if((a_what==lines)||(a_what==faces_and_lines)) {
float pvbx = 0;
float pvby = 0;
float pvbz = 0;
float pvex,pvey,pvez;
vec3d unitNormal;
vec3d* pV = sbPolyhedron.GetPV();
bool notLastFace;
do {
notLastFace = sbPolyhedron.GetNextUnitNormal(unitNormal);
// Treat edges :
int edgeFlag = 1;
int prevEdgeFlag = edgeFlag;
bool notLastEdge;
bool firstEdge = true;
do {
int index;
notLastEdge = sbPolyhedron.GetNextVertexIndex(index,edgeFlag);
vec3d* vertex = pV+index; //WARNING : must not be modified !
if(!reduced_wire_frame) edgeFlag = 1;
if(firstEdge) {
if(edgeFlag) {
pvbx = (float)(*vertex)[0];
pvby = (float)(*vertex)[1];
pvbz = (float)(*vertex)[2];
} else {
}
firstEdge = false;
prevEdgeFlag = edgeFlag;
} else {
if(edgeFlag!=prevEdgeFlag) {
if(edgeFlag) { // Pass to a visible edge :
pvbx = (float)(*vertex)[0];
pvby = (float)(*vertex)[1];
pvbz = (float)(*vertex)[2];
} else { // Pass to an invisible edge :
pvex = (float)(*vertex)[0];
pvey = (float)(*vertex)[1];
pvez = (float)(*vertex)[2];
m_xyzs.push_back(pvbx);
m_xyzs.push_back(pvby);
m_xyzs.push_back(pvbz);
m_xyzs.push_back(pvex);
m_xyzs.push_back(pvey);
m_xyzs.push_back(pvez);
}
prevEdgeFlag = edgeFlag;
} else {
if(edgeFlag) {
pvex = (float)(*vertex)[0];
pvey = (float)(*vertex)[1];
pvez = (float)(*vertex)[2];
m_xyzs.push_back(pvbx);
m_xyzs.push_back(pvby);
m_xyzs.push_back(pvbz);
m_xyzs.push_back(pvex);
m_xyzs.push_back(pvey);
m_xyzs.push_back(pvez);
pvbx = pvex;
pvby = pvey;
pvbz = pvez;
} else {
}
}
}
} while (notLastEdge);
} while (notLastFace);
}
}
const std::vector<float>& xyzs() const {return m_xyzs;}
protected:
void _clear(){
tools_vforit(prims_t,m_primss,it) raw_clear(*it);
m_primss.clear();
m_xyzs.clear();
}
protected:
std::vector<float> m_xyzs;
//gluTess
tessellate* m_tess;
std::vector<prims_t> m_primss;
size_t m_size;
bool m_draw_edges;
};
}}
#endif
+27 -1
View File
@@ -77,17 +77,40 @@ public:
virtual sg::render_manager& render_manager() = 0; //sg:: is needed.
public:
render_action(std::ostream& a_out,unsigned int a_ww,unsigned int a_wh)
:parent(a_out,a_ww,a_wh){}
:parent(a_out,a_ww,a_wh)
,m_do_transparency(false)
,m_have_to_do_transparency(false)
{}
virtual ~render_action(){}
public:
render_action(const render_action& a_from)
:parent(a_from)
,m_do_transparency(a_from.m_do_transparency)
,m_have_to_do_transparency(a_from.m_have_to_do_transparency)
{}
render_action& operator=(const render_action& a_from){
parent::operator=(a_from);
m_do_transparency = a_from.m_do_transparency;
m_have_to_do_transparency = a_from.m_have_to_do_transparency;
return *this;
}
public:
void set_do_transparency(bool a_value) {m_do_transparency = a_value;}
bool do_transparency() const {return m_do_transparency;}
void set_have_to_do_transparency(bool a_value) {m_have_to_do_transparency = a_value;}
bool have_to_do_transparency() const {return m_have_to_do_transparency;}
bool have_to_render() {
bool transparent = state().m_color.a()!=1?true:false;
if(transparent) {
if(m_do_transparency) return true;
m_have_to_do_transparency = true;
return false;
}
if(m_do_transparency) return false;
return true;
}
void load_matrices_to_identity() {
load_proj_matrix(m_identity);
load_model_matrix(m_identity);
@@ -288,6 +311,9 @@ public:
}
a_out << "dump_vertex_array_xy : end." << std::endl;
}
protected:
bool m_do_transparency;
bool m_have_to_do_transparency;
};
}}
+150
View File
@@ -0,0 +1,150 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
//
// Helper functions to search node(s) in a scene graph.
//
#ifndef tools_sg_search
#define tools_sg_search
#include "search_action"
#include "node"
namespace tools {
namespace sg {
template <class NODE>
inline NODE* find_first_node_of_class(std::ostream& a_out,node& a_from) {
search_action action(a_out);
action.reset();
action.set_what(search_action::search_node_of_class);
action.set_stop_at_first(true);
action.set_class(NODE::s_class());
a_from.search(action);
const std::vector<void*>& _objs = action.objs();
if(_objs.empty()) return 0;
return (NODE*)_objs[0];
}
inline node* find_first_node_with_class(std::ostream& a_out,node& a_from,const std::string& a_class) {
search_action action(a_out);
action.reset();
action.set_what(search_action::search_node_of_class);
action.set_stop_at_first(true);
action.set_class(a_class);
a_from.search(action);
const std::vector<void*>& _objs = action.objs();
if(_objs.empty()) return 0;
return (node*)_objs[0];
}
}}
#include "path"
namespace tools {
namespace sg {
inline const path_t& find_path(search_action& a_action,node& a_from,node& a_node,bool a_verbose) {
a_action.reset();
a_action.set_what(search_action::search_path_to_node);
a_action.set_node(&a_node);
a_from.search(a_action);
if(!a_action.done()) {
if(a_verbose) {
a_action.out() << "tools::sg::find_path :"
<< " not found node of class " << a_node.s_cls()
<< " from head node of class " << a_from.s_cls()
<< std::endl;
}
a_action.clear_path();
return a_action.path();
}
if(a_verbose) {
a_action.out() << "tools::sg::find_path :"
<< " found node of class " << a_node.s_cls()
<< " from head node of class " << a_from.s_cls()
<< std::endl;
}
const path_t& path = a_action.path();
if(path.empty()) {
if(a_verbose) {
a_action.out() << "tools::sg::find_path :"
<< " node has no path !"
<< std::endl;
}
return path;
}
if(&a_node!=path[path.size()-1]) {
a_action.out() << "tools::sg::find_path :"
<< " node / path tail mismatch !"
<< " node " << a_node.s_cls()
<< " tail " << path[path.size()-1]->s_cls()
<< std::endl;
a_action.clear_path();
return a_action.path();
}
return path;
}
inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from,const std::string& a_class){
a_action.reset();
a_action.set_what(search_action::search_path_to_node_of_class);
a_action.set_class(a_class);
a_from.search(a_action);
return a_action.paths();
}
template <class NODE>
inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from){
a_action.reset();
a_action.set_what(search_action::search_path_to_node_of_class);
a_action.set_class(NODE::s_class());
a_from.search(a_action);
return a_action.paths();
}
template <class NODE>
inline NODE* find_ancestor(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) {
search_action action(a_out);
return rfind<NODE>(find_path(action,a_from,a_node,a_verbose));
}
template <class CONTAINER>
inline CONTAINER* find_container(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) {
search_action action(a_out);
return container<CONTAINER>(find_path(action,a_from,a_node,a_verbose));
}
template <class NODE>
inline NODE* search_node(std::ostream& a_out,node& a_from) {
search_action sa(a_out);
const paths_t& paths = find_paths<NODE>(sa,a_from);
tools_vforcit(path_t,paths,it) {
NODE* _node = tail<NODE>(*it);
if(_node) return _node;
}
return 0;
}
template <class SELECTABLE>
inline SELECTABLE* search_selectable(std::ostream& a_out,node& a_from) {
search_action sa(a_out);
const paths_t& paths = find_paths<SELECTABLE>(sa,a_from);
tools_vforcit(path_t,paths,it) {
SELECTABLE* _node = tail<SELECTABLE>(*it);
if(_node && _node->border_visible.value()) return _node;
}
/*
tools_vforcit(sg::path_t,paths,it) {
SELECTABLE* _node = sg::tail<SELECTABLE>(*it);
if(_node) return _node;
}
*/
return 0;
}
}}
#endif
@@ -1,104 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_set_plotter_camera
#define tools_sg_set_plotter_camera
#include "plotter"
#include "ortho"
namespace tools {
namespace sg {
inline void set_plotter_camera(float a_XSIZ,float a_YSIZ,float a_ZSIZ,
plotter& a_plotter,ortho& a_camera,unsigned int a_ww,unsigned int a_wh) {
if(!a_ww || !a_wh) return;
a_plotter.width.value(a_XSIZ);
a_plotter.height.value(a_YSIZ);
a_plotter.depth.value(a_ZSIZ);
enum plotter_viewport_mapping {
pvp_adjust_viewport,
pvp_leave_alone
};
plotter_viewport_mapping pvp = pvp_adjust_viewport;
//plotter_viewport_mapping pvp = pvp_leave_alone;
typedef plotter::shape_type st_t;
st_t plotter_shape = plotter::xy;
float aspect = float(a_ww)/float(a_wh);
{float XSIZ = a_plotter.width.value();
float YSIZ = a_plotter.height.value();
if((plotter_shape==plotter::xy) &&
(pvp==pvp_adjust_viewport)) {
// Adjust the plotter XSIZ and YSIZ so that YSIZ matches viewport height
// and plotter XSIZ matches viewport width.
// It it the CERN-ROOT and osc-plot logic.
if(aspect>=1) { //w>h
// camera must match in height YSIZ. Adjust XSIZ.
a_plotter.width.value(YSIZ * aspect);
} else {
// camera must match in width XSIZ. Adjust YSIZ.
a_plotter.height.value(XSIZ / aspect);
}
}}
{float camera_znear = 0;
float camera_zfar = 0;
float camera_z_pos = 0;
// if camera ortho :
float camera_height = 0;
float XSIZ = a_plotter.width.value();
float YSIZ = a_plotter.height.value();
float z = 4 * a_plotter.depth.value();
camera_z_pos = z;
camera_znear = 0.01F*z;
camera_zfar = 100*z;
//cam ortho :
if(plotter_shape==plotter::xyz) {
camera_height = YSIZ;
} else {
if(pvp==pvp_leave_alone) {
// Adjust camera so that plotter XSIZ/YSIZ be not distorded.
// If viewport aspect ratio > plotter aspect ratio
// the plotter YSIZ matches the viewport height. If not
// it is the plotter XSIZ that will match the viewport width.
// It is the PAW logic for one region.
float plotterAspect = XSIZ/YSIZ;
if(aspect<plotterAspect) {
camera_height = XSIZ / aspect;
} else {
camera_height = YSIZ;
}
} else if(pvp==pvp_adjust_viewport) {
camera_height = YSIZ;
}
}
a_camera.height.value(camera_height);
a_camera.znear.value(camera_znear);
a_camera.zfar.value(camera_zfar);
a_camera.position.value(vec3f(0,0,camera_z_pos));
a_camera.orientation.value(rotf(vec3f(0,0,1),0));}
}
inline void set_plotter_camera(plotter& a_plotter,ortho& a_camera,unsigned int a_ww,unsigned int a_wh) {
//PAW logic :
float xfac = 1.0F/20.0F; //0.05
float yfac = 1.0F/20.0F; //0.05
float XSIZ = 20 * xfac; //1 //page width
float YSIZ = 20 * yfac; //1 //page height
float zfac = 1.0F/20.0F; //0.05
float ZSIZ = 20 * zfac; //1 //page depth
set_plotter_camera(XSIZ,YSIZ,ZSIZ,a_plotter,a_camera,a_ww,a_wh);
}
}}
#endif
-37
View File
@@ -1,37 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_sf_vec2f
#define tools_sg_sf_vec2f
#include "sf_vec"
#include "../lina/vec2f"
#include "../HEADER"
namespace tools {
namespace sg {
class sf_vec2f : public sf_vec<vec2f,float> {
typedef sf_vec<vec2f,float> _parent;
TOOLS_HEADER(sf_vec2f,tools::sg::sf_vec2f,_parent)
public:
sf_vec2f():parent(){}
sf_vec2f(const vec2f& a_v):parent(a_v){}
virtual ~sf_vec2f(){}
public:
sf_vec2f(const sf_vec2f& a_from):parent(a_from){}
sf_vec2f& operator=(const sf_vec2f& a_from){
parent::operator=(a_from);
return *this;
}
public:
sf_vec2f& operator+=(const vec2f& a_value) {parent::operator+=(a_value);return *this;}
public: //for iv2sg
void setValue(const vec2f& a_v) {value(a_v);}
void setValue(float a_0,float a_1) {value(vec2f(a_0,a_1));}
};
}}
#endif
-532
View File
@@ -1,532 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_tessellate
#define tools_sg_tessellate
//#include "../tessellate"
#include <vector>
#include "../glprims"
#ifdef TOOLS_MEM
#include "../mem"
#include "../S_STRING"
#endif
namespace tools {
namespace sg {
class tess_prim {
#ifdef TOOLS_MEM
TOOLS_SCLASS(tools::sg::tess_prim)
#endif
public:
tess_prim()
:m_mode(gl::triangles())
,m_size(0)
,m_pos_coords(0)
,m_pos_norms(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tess_prim(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
tess_prim(const tess_prim& a_from)
:m_mode(a_from.m_mode)
,m_coords(a_from.m_coords)
,m_norms(a_from.m_norms)
,m_size(a_from.m_size)
,m_pos_coords(a_from.m_pos_coords)
,m_pos_norms(a_from.m_pos_norms)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
tess_prim& operator=(const tess_prim& a_from){
if(&a_from==this) return *this;
m_mode = a_from.m_mode;
m_coords = a_from.m_coords;
m_norms = a_from.m_norms;
m_size = a_from.m_size;
m_pos_coords = a_from.m_pos_coords;
m_pos_norms = a_from.m_pos_norms;
return *this;
}
public:
gl::mode_t m_mode;
std::vector<float> m_coords;
std::vector<float> m_norms;
//for gsto :
size_t m_size;
typedef size_t bufpos;
bufpos m_pos_coords;
bufpos m_pos_norms;
};
}}
#include "../vdata"
#include "../forit"
#include "primitive_visitor"
#include <ostream>
#include <cmath> //sqrt
#ifdef TOOLS_MEM
#include "../S_STRING"
#include "../mem"
#endif
#include "../glutess/glutess"
namespace tools {
namespace sg {
class tessellate {
#ifdef TOOLS_MEM
TOOLS_SCLASS(tools::sg::tessellate);
#endif
public:
tessellate(std::ostream& a_out):m_out(a_out),m_tobj(0) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_tobj = gluNewTess();
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_BEGIN_DATA, (Func)begin_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_END_DATA, (Func)end_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_VERTEX_DATA, (Func)vertex_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_COMBINE_DATA,(Func)combine_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_ERROR_DATA, (Func)error_cbk);
//set winding rule to positive => no holes
::gluTessProperty(m_tobj,(GLUenum)GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_POSITIVE);
//m_out << "tools::sg::tessellate::tessellate :"
// << " GL_TRIANGLE_STRIP " << GL_TRIANGLE_STRIP
// << " GL_TRIANGLE_FAN " << GL_TRIANGLE_FAN
// << " GL_TRIANGLES " << GL_TRIANGLES
// << std::endl;
}
virtual ~tessellate(){
::gluDeleteTess(m_tobj);
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
tessellate(const tessellate& a_from):m_out(a_from.m_out),m_tobj(0) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_tobj = gluNewTess();
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_BEGIN_DATA, (Func)begin_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_END_DATA, (Func)end_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_VERTEX_DATA, (Func)vertex_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_COMBINE_DATA,(Func)combine_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_ERROR_DATA, (Func)error_cbk);
//set winding rule to positive => no holes
::gluTessProperty(m_tobj,(GLUenum)GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_POSITIVE);
}
tessellate& operator=(const tessellate& a_from){
if(&a_from==this) return *this;
_clear();
return *this;
}
public:
typedef std::vector<tess_prim*> prims_t;
void do_it(size_t a_npt,const double* a_contour,prims_t& a_prims){
::gluTessBeginPolygon(m_tobj,this);
::gluTessBeginContour(m_tobj);
double* pos = (double*)a_contour;
for(size_t i=0;i<a_npt;i++,pos+=3) {
::gluTessVertex(m_tobj,pos,pos);
}
::gluTessEndContour(m_tobj);
a_prims.clear();
m_prims = &a_prims;
m_combine_trids_num = 0;
::gluTessEndPolygon(m_tobj); //trigger callbacks and fill a_prims.
}
void clear(){_clear();}
protected:
typedef _GLUfuncptr Func;
static void GLUAPIENTRY begin_cbk(GLUenum a_which,void* a_this) {
tessellate& self = *((tessellate*)a_this);
self.m_prims->push_back(new tess_prim());
tess_prim& prim = *(self.m_prims->back());
prim.m_mode = a_which;
prim.m_coords.reserve(12); //4 points.
prim.m_norms.reserve(12);
self.m_coords = &prim.m_coords;
//::printf("tools::sg::tessellate::begin_cbk : %d : STRIP %d FAN %d TRIS %d\n",
// a_which,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN,GL_TRIANGLES);
}
static void GLUAPIENTRY vertex_cbk(void* a_vertex,void* a_this) {
tessellate& self = *((tessellate*)a_this);
double* vertex = (double*)a_vertex;
self.m_coords->push_back(float(vertex[0]));
self.m_coords->push_back(float(vertex[1]));
self.m_coords->push_back(float(vertex[2]));
}
typedef float _vec3f[3];
static void GLUAPIENTRY end_cbk(void* a_this){
tessellate& self = *((tessellate*)a_this);
tess_prim& prim = *(self.m_prims->back());
//self.m_out << "tools::sg::tessellate::end_cbk : "
// << prim.m_coords.size()/3 << std::endl;
add_prm aprm(self.m_out,prim.m_norms);
float* data = vec_data<float>(prim.m_coords);
bool ok = true;
if(prim.m_mode==gl::triangles()) {
if(!aprm.add_triangles(prim.m_coords.size(),data,false)) {
self.m_out << "tools::sg::tessellate::end_cbk : "
<< " add_triangles failed."
<< std::endl;
ok = false;
}
} else if(prim.m_mode==gl::triangle_strip()) {
if(!aprm.add_triangle_strip(prim.m_coords.size(),data,false)){
self.m_out << "tools::sg::tessellate::end_cbk : "
<< " add_triangle_strip failed."
<< std::endl;
ok = false;
}
} else if(prim.m_mode==gl::triangle_fan()) {
if(!aprm.add_triangle_fan(prim.m_coords.size(),data,false)) {
self.m_out << "tools::sg::tessellate::end_cbk : "
<< " add_triangle_fan failed."
<< std::endl;
ok = false;
}
} else {
self.m_out << "tools::sg::tessellate::end_cbk : "
<< " mode " << prim.m_mode << " not yet treated."
<< std::endl;
ok = false;
}
if(!ok) {
size_t num = prim.m_coords.size();
self.m_out << "tools::sg::tessellate::end_cbk :"
<< " primitive anomaly."
<< " num points " << num
<< " mode " << prim.m_mode
<< " (TRIANGLES=4, STRIP=5, FAN=6)."
<< std::endl;
float* pos = vec_data<float>(prim.m_coords);
for(size_t ipt=0;ipt<num;ipt++) {
self.m_out << " " << ipt << " :"
<< " " << *(pos+0)
<< " " << *(pos+1)
<< " " << *(pos+2)
<< std::endl;
pos += 3;
}
prim.m_coords.clear();
prim.m_norms.clear();
}
}
static void GLUAPIENTRY combine_cbk(double a_coords[3],
void* /*a_vertex_data*/[4],
float /*a_weight*/[4],
void** a_data_out,
void* a_this) {
tessellate& self = *((tessellate*)a_this);
double* v = self.add_combine_vec3d(a_coords[0],a_coords[1],a_coords[2]);
//if(!v) ???
*a_data_out = v;
}
static void GLUAPIENTRY error_cbk(GLUenum,void*) {
//const GLubyte* estring = gluErrorString(aErrorCode);
//::fprintf(stderr, "Tessellation Error: %s\n", estring);
//SbTessContour* This = (SbTessContour*)aThis;
//This->setError(true);
}
double* add_combine_vec3d(double a_x,double a_y,double a_z) {
double* v = 0;
if(m_combine_trids_num>=m_combine_trids.size()) {
v = new double[3];
m_combine_trids.push_back(v);
} else {
v = m_combine_trids[m_combine_trids_num];
}
m_combine_trids_num++;
v[0] = a_x;
v[1] = a_y;
v[2] = a_z;
return v;
}
void _clear() {
tools_vforit(double*,m_combine_trids,it) delete [] *it;
m_combine_trids.clear();
m_combine_trids_num = 0;
}
protected:
class add_prm : public primitive_visitor {
protected:
virtual bool project(float&,float&,float&,float&) {return true;}
virtual bool add_point(float,float,float,float) {return false;}
virtual bool add_point(float,float,float,float,
float,float,float,float) {return false;}
virtual bool add_line(float,float,float,float,
float,float,float,float) {return false;}
virtual bool add_line(float,float,float,float,float,float,float,float,
float,float,float,float,float,float,float,float) {
return false;
}
virtual bool add_triangle(float a_p1x,float a_p1y,float a_p1z,float,
float a_p2x,float a_p2y,float a_p2z,float,
float a_p3x,float a_p3y,float a_p3z,float){
float vx = a_p2x-a_p1x;
float vy = a_p2y-a_p1y;
float vz = a_p2z-a_p1z;
float wx = a_p3x-a_p2x;
float wy = a_p3y-a_p2y;
float wz = a_p3z-a_p2z;
// vx wx
// vy ^ wy
// vz wz
float cx = vy*wz-vz*wy;
float cy = vz*wx-vx*wz;
float cz = vx*wy-vy*wx;
float len = (float)::sqrt(cx*cx + cy*cy + cz*cz);
if(!len) {
//m_out << "tools::sg::tessellate::add_prm : null normal."
// << std::endl;
} else {
cx /= len;
cy /= len;
cz /= len;
}
if(m_mode==gl::triangles()) {
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
} else if( (m_mode==gl::triangle_strip()) ||
(m_mode==gl::triangle_fan()) ){
if(m_norms.empty()) { //startup : three vertices.
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
} else { //one vertex :
m_norms.push_back(cx);
m_norms.push_back(cy);
m_norms.push_back(cz);
}
}
return true;
}
virtual bool add_triangle(float a_p1x,float a_p1y,float a_p1z,float a_p1w,
float,float,float,float,
float a_p2x,float a_p2y,float a_p2z,float a_p2w,
float,float,float,float,
float a_p3x,float a_p3y,float a_p3z,float a_p3w,
float,float,float,float){
return add_prm::add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
a_p2x,a_p2y,a_p2z,a_p2w,
a_p3x,a_p3y,a_p3z,a_p3w);
}
virtual bool project_normal(float& a_x,float& a_y,float& a_z) {
(void)a_x;(void)a_y;(void)a_z;
return true;
}
virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w,
float a_nx,float a_ny,float a_nz) {
(void)a_x;(void)a_y;(void)a_z;(void)a_w;
(void)a_nx;(void)a_ny;(void)a_nz;
return false;
}
virtual bool add_point_normal(float a_x,float a_y,float a_z,float a_w,
float a_nx,float a_ny,float a_nz,
float a_r,float a_g,float a_b,float a_a) {
(void)a_x;(void)a_y;(void)a_z;(void)a_w;
(void)a_nx;(void)a_ny;(void)a_nz;
(void)a_r;(void)a_g;(void)a_b;(void)a_a;
return false;
}
virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw,
float a_bnx,float a_bny,float a_bnz,
float a_ex,float a_ey,float a_ez,float a_ew,
float a_enx,float a_eny,float a_enz) {
(void)a_bx;(void)a_by;(void)a_bz;(void)a_bw;
(void)a_bnx;(void)a_bny;(void)a_bnz;
(void)a_ex;(void)a_ey;(void)a_ez;(void)a_ew;
(void)a_enx;(void)a_eny;(void)a_enz;
return false;
}
virtual bool add_line_normal(float a_bx,float a_by,float a_bz,float a_bw,
float a_bnx,float a_bny,float a_bnz,
float a_br,float a_bg,float a_bb,float a_ba,
float a_ex,float a_ey,float a_ez,float a_ew,
float a_enx,float a_eny,float a_enz,
float a_er,float a_eg,float a_eb,float a_ea){
(void)a_bx;(void)a_by;(void)a_bz;(void)a_bw;
(void)a_bnx;(void)a_bny;(void)a_bnz;
(void)a_br;(void)a_bg;(void)a_bb;(void)a_ba;
(void)a_ex;(void)a_ey;(void)a_ez;(void)a_ew;
(void)a_enx;(void)a_eny;(void)a_enz;
(void)a_er;(void)a_eg;(void)a_eb;(void)a_ea;
return false;
}
virtual bool add_triangle_normal(
float a_p1x,float a_p1y,float a_p1z,float a_p1w,
float a_n1x,float a_n1y,float a_n1z,
float a_p2x,float a_p2y,float a_p2z,float a_p2w,
float a_n2x,float a_n2y,float a_n2z,
float a_p3x,float a_p3y,float a_p3z,float a_p3w,
float a_n3x,float a_n3y,float a_n3z) {
add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
a_p2x,a_p2y,a_p2z,a_p2w,
a_p3x,a_p3y,a_p3z,a_p3w);
//m_this.m_triangles.add_normal(a_n1x,a_n1y,a_n1z);
//m_this.m_triangles.add_normal(a_n2x,a_n2y,a_n2z);
//m_this.m_triangles.add_normal(a_n3x,a_n3y,a_n3z);
(void)a_n1x;(void)a_n1y;(void)a_n1z;
(void)a_n2x;(void)a_n2y;(void)a_n2z;
(void)a_n3x;(void)a_n3y;(void)a_n3z;
return true;
}
virtual bool add_triangle_normal(
float a_p1x,float a_p1y,float a_p1z,float a_p1w,
float a_n1x,float a_n1y,float a_n1z,
float a_r1,float a_g1,float a_b1,float a_a1,
float a_p2x,float a_p2y,float a_p2z,float a_p2w,
float a_n2x,float a_n2y,float a_n2z,
float a_r2,float a_g2,float a_b2,float a_a2,
float a_p3x,float a_p3y,float a_p3z,float a_p3w,
float a_n3x,float a_n3y,float a_n3z,
float a_r3,float a_g3,float a_b3,float a_a3){
add_triangle(a_p1x,a_p1y,a_p1z,a_p1w,
a_r1,a_g1,a_b1,a_a1,
a_p2x,a_p2y,a_p2z,a_p2w,
a_r2,a_g2,a_b2,a_a2,
a_p3x,a_p3y,a_p3z,a_p3w,
a_r3,a_g3,a_b3,a_a3);
//m_this.m_triangles.add_normal(a_n1x,a_n1y,a_n1z);
//m_this.m_triangles.add_normal(a_n2x,a_n2y,a_n2z);
//m_this.m_triangles.add_normal(a_n3x,a_n3y,a_n3z);
(void)a_n1x;(void)a_n1y;(void)a_n1z;
(void)a_n2x;(void)a_n2y;(void)a_n2z;
(void)a_n3x;(void)a_n3y;(void)a_n3z;
return true;
}
public:
add_prm(std::ostream& a_out,std::vector<float>& a_norms)
:m_out(a_out)
,m_norms(a_norms)
{}
virtual ~add_prm(){}
public:
add_prm(const add_prm& a_from):primitive_visitor(a_from),m_out(a_from.m_out),m_norms(a_from.m_norms) {}
add_prm& operator=(const add_prm& a_from){
primitive_visitor::operator=(a_from);
return *this;
}
protected:
std::ostream& m_out;
public:
std::vector<float>& m_norms;
};
protected:
std::ostream& m_out;
GLUtesselator* m_tobj;
std::vector<float>* m_coords;
std::vector<double*> m_combine_trids;
size_t m_combine_trids_num;
prims_t* m_prims;
};
/*
class tessellate_factory {
#ifdef TOOLS_MEM
TOOLS_SCLASS(tools::sg::tessellate_factory);
#endif
public:
tessellate_factory(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tessellate_factory(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
tessellate_factory(const tessellate_factory& a_from) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
tessellate_factory& operator=(const tessellate_factory&){
return *this;
}
public:
virtual tessellate* create(std::ostream& a_out) {
return new tessellate(a_out);
}
};
*/
}}
#endif
+32 -12
View File
@@ -875,7 +875,7 @@ protected:
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_COMBINE_DATA,(Func)combine_cbk);
::gluTessCallback(m_tobj,(GLUenum)GLU_TESS_ERROR_DATA, (Func)error_cbk);
#else
// NOTE : the gluTessCallback_<enum>() functions are inlib/glutess specific.
// NOTE : the gluTessCallback_<enum>() functions are tools/glutess specific.
// They had been introduced to avoid g++-8.1.0 warnings :
// warnings : cast between incompatible function types.
::gluTessCallback_GLU_TESS_BEGIN_DATA (m_tobj,begin_cbk);
@@ -1775,26 +1775,45 @@ protected:
::FT_Done_Face(m_face);
m_face = 0;
}
if(font.value().empty()) {
a_out << "tools::sg::text_freetype::load_face :"
<< " no font file given."
<< " no font given."
<< std::endl;
return;
}
std::string file;
//if(tools::file::exists(font.value())) { //look in current directory.
// file = font.value(); //ok
//} else if(!inlib::find_with_dirs(a_out,font_dirs.values(),font.value(),file,false)) {
if(!tools::find_with_env(a_out,s_TOOLS_FONT_PATH(),font.value(),file,false)) {
// look for embedded fonts:
{unsigned int size;
const unsigned char* buffer;
if(parent::find_embedded_font(font.value(),size,buffer)) {
FT_Error error =
::FT_New_Memory_Face(m_library,(const FT_Byte*)buffer,(FT_Long)size,0,&m_face);
if(error) {
a_out << "tools::sg::text_freetype::load_face :"
<< " font file not found for font "
<< tools::sout(font.value()) << "."
<< " FT_New_Memory_Face : error : " << serror(error) << "."
<< std::endl;
m_face = 0;
return;
}
//}
if(m_verbose) a_out << "tools::sg::text_freetype::load_face : load embedded font ok." << std::endl;
return;
}}
std::string file;
if(parent::find_font_with_finders(font.value(),file)) {
} else {
tools::find_with_env(a_out,s_TOOLS_FONT_PATH(),font.value(),file,false);
}
if(file.empty()) {
a_out << "tools::sg::text_freetype::load_face :"
<< " font file not found for font "
<< tools::sout(font.value()) << "."
<< std::endl;
return;
}
if(m_verbose) {
a_out << "tools::sg::text_freetype::load_face :"
@@ -2128,7 +2147,7 @@ protected:
FT_Library m_library;
FT_Face m_face;
unsigned short m_encoding_offset;
bool m_verbose; //append _ to avoid clash with inlib/sg/guib::m_verbose
bool m_verbose; //append _ to avoid clash with tools/sg/guib::m_verbose
////////////////////////////////////////////////////////
/// outline ////////////////////////////////////////////
////////////////////////////////////////////////////////
@@ -2174,4 +2193,5 @@ protected:
}}
#endif
@@ -35,7 +35,14 @@ public:
float zz = 0;
a_action.load_matrices_to_identity();
{tools::mat4f _mtx;
_mtx.set_translate(x,y,zz);
if(!m_bitmaps.size()) {
if(state.m_ww) _mtx.mul_scale(float(state.m_wh)/float(state.m_ww),1,1);
}
a_action.load_model_matrix(_mtx);}
///////////////////////////////////////////////////////////
/// lines /////////////////////////////////////////////////
///////////////////////////////////////////////////////////
@@ -45,11 +52,7 @@ public:
size_t num = item.second;
if(!num) continue;
const float* data = tools::vec_data<float>(m_xys)+pos;
float* vp = _trans3(num,data,x,y,zz); //have an extra z for Windows GL.
if(vp) {
a_action.draw_vertex_array(tools::gl::line_strip(),num*3,vp);
delete [] vp;
}
a_action.draw_vertex_array_xy(tools::gl::line_strip(),num*2,data);
}}
///////////////////////////////////////////////////////////
@@ -65,21 +68,13 @@ public:
// << std::endl;
const float* data = tools::vec_data<float>(m_xys)+pos;
float* vp = _trans3(num,data,x,y,zz); //have an extra z for Windows GL.
if(vp) {
a_action.draw_vertex_array((*it).first,num*3,vp);
delete [] vp;
}
a_action.draw_vertex_array_xy((*it).first,num*2,data);
}}
///////////////////////////////////////////////////////////
/// bitmap ////////////////////////////////////////////////
///////////////////////////////////////////////////////////
if(m_bitmaps.size()) {
tools::mat4f _m;
_m.set_translate(x,y,zz);
a_action.load_model_matrix(_m);
#if defined(ANDROID) /*|| TARGET_OS_IPHONE*/
// we do not have transparent texture here (see also gl/tex_img() that does img/4-bytes => img/3-bytes) :
{tools::sg::state& _state = a_action.state();
@@ -106,6 +101,8 @@ public:
}
virtual void pick(tools::sg::pick_action& a_action) {
const tools::sg::state& state = a_action.state();
{bool _char_height_touched = char_height_touched(a_action.state());
if(touched()||_char_height_touched) {
update_sg(a_action.out(),font.touched(),a_action.state());
@@ -118,10 +115,14 @@ public:
a_action.set_matrices_to_identity();
a_action.model_matrix().set_translate(x,y,zz);
if(!m_bitmaps.size()) {
if(state.m_ww) a_action.model_matrix().mul_scale(float(state.m_wh)/float(state.m_ww),1,1);
}
///////////////////////////////////////////////////////////
/// lines /////////////////////////////////////////////////
///////////////////////////////////////////////////////////
{tools_vforcit(line_t,m_lines,it) {
const line_t& item = *it;
size_t pos = item.first;
@@ -166,10 +167,9 @@ public:
/// bitmap ////////////////////////////////////////////////
///////////////////////////////////////////////////////////
if(m_bitmaps.size()) {
a_action.model_matrix().set_translate(x,y,zz);
m_bitmaps.pick(a_action);
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
@@ -245,18 +245,6 @@ protected:
height.value_no_cmp(old_height);
}
float* _trans3(size_t a_num,const float* a_data,float a_x,float a_y,float a_z) {
float* vp = new float[a_num*3];
if(!vp) return 0;
float* pos = vp;
float* pda = (float*)a_data;
for(size_t index=0;index<a_num;index++){
*pos = *pda + a_x;pos++;pda++;
*pos = *pda + a_y;pos++;pda++;
*pos = a_z;pos++;
}
return vp;
}
float* _trans2(size_t a_num,const float* a_data,float a_x,float a_y) {
float* vp = new float[a_num*2];
if(!vp) return 0;
+10 -12
View File
@@ -33,12 +33,12 @@ public:
get_segments(segs); //must be after changing the height.
a_action.load_matrices_to_identity();
{std::vector<float>::iterator it;
for(it=segs.begin();it!=segs.end();) {
*it += x;it++; //Android don't like *it++.
*it += y;it++;
}}
{tools::mat4f _mtx;
_mtx.set_translate(x,y,0);
if(state.m_ww) _mtx.mul_scale(float(state.m_wh)/float(state.m_ww),1,1);
a_action.load_proj_matrix(_mtx);}
a_action.draw_vertex_array_xy(gl::lines(),segs);
a_action.load_matrices_from_state();
@@ -65,12 +65,10 @@ public:
get_segments(segs);
a_action.set_matrices_to_identity();
{std::vector<float>::iterator it;
for(it=segs.begin();it!=segs.end();) {
*it += x;it++;
*it += y;it++;
}}
{tools::mat4f& _mtx = a_action.model_matrix();
_mtx.set_translate(x,y,0);
if(state.m_ww) _mtx.mul_scale(float(state.m_wh)/float(state.m_ww),1,1);}
a_action.add__lines_xy(*this,segs);
+128
View File
@@ -0,0 +1,128 @@
// Copyright (C) 2018, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sg_write_paper
#define tools_sg_write_paper
// To traverse a scene graph and "export" it at various file formats
// by using various rendering actions.
// For example by using gl2ps_action, handle the formats:
// gl2ps_eps: gl2ps producing eps
// gl2ps_ps: gl2ps producing ps
// gl2ps_pdf: gl2ps producing pdf
// gl2ps_svg: gl2ps producing svg
// gl2ps_tex: gl2ps producing tex
// gl2ps_pgf: gl2ps producing pgf
// By using the zb_action (zb for zbuffer):
// zb_ps: tools::sg offscreen zbuffer put in a PostScript file.
// zb_png: zbuffer put in a png file. It needs to provide a "png_writer" function.
// zb_jpeg: zbuffer put in a jpeg file. It needs to provide a "jpeg_writer" function.
#include "zb_action"
#include "node"
#include "gl2ps_action"
#include "../wps"
#include "../typedefs"
#include "../touplow"
namespace tools {
namespace sg {
typedef bool (*png_writer)(std::ostream&,const std::string&,
unsigned char*,unsigned int,unsigned int,unsigned int);
typedef bool (*jpeg_writer)(std::ostream&,const std::string&,
unsigned char*,unsigned int,unsigned int,unsigned int,int);
inline bool write_paper(std::ostream& a_out,
gl2ps_manager& a_gl2ps_mgr,zb_manager& a_zb_mgr,
png_writer a_png_writer,jpeg_writer a_jpeg_writer,
float a_back_r,float a_back_g,float a_back_b,float a_back_a,
node& a_scene_graph,
unsigned int a_width,unsigned int a_height,
const std::string& a_file,const std::string& a__format) {
if(!a_width || !a_height) return false;
std::string a_format = a__format;
tolowercase(a_format); //handle legacy.
int gl2ps_format;
if(s2format(a_format,gl2ps_format)) {
gl2ps_action action(a_gl2ps_mgr,a_out,a_width,a_height);
action.clear_color(a_back_r,a_back_g,a_back_b,a_back_a);
if(!action.open(a_file,gl2ps_format)) return false;
a_scene_graph.render(action);
action.close();
return true;
}
zb_action action(a_zb_mgr,a_out,a_width,a_height);
action.zbuffer().clear_color_buffer(0);
action.add_color(a_back_r,a_back_g,a_back_b,a_back_a);
action.zbuffer().clear_depth_buffer();
a_scene_graph.render(action);
if((a_format=="zb_ps")||(a_format=="inzb_ps")) {
wps wps(a_out);
if(!wps.open_file(a_file)) {
a_out << "tools::sg::write_paper : can't open " << a_file << "." << std::endl;
return false;
}
wps.PS_BEGIN_PAGE();
wps.PS_PAGE_SCALE(float(a_width),float(a_height));
wps.PS_IMAGE(a_width,a_height,wps::rgb_4,zb_action::get_rgb,&action);
wps.PS_END_PAGE();
wps.close_file();
return true;
}
if((a_format=="zb_png")||(a_format=="inzb_png")) {
if(!a_png_writer) {
a_out << "tools::sg::write_paper : no png_writer given." << std::endl;
return false;
}
size_t sz;
unsigned char* buffer = action.get_rgbas(sz);
if(!buffer) {
a_out << "tools::sg::write_paper : can't get rgba image." << std::endl;
return false;
}
if(!a_png_writer(a_out,a_file,buffer,a_width,a_height,4)) {
a_out << "tools::sg::write_paper : tools::png::write() failed." << std::endl;
delete [] buffer;
return false;
}
delete [] buffer;
return true;
}
if((a_format=="zb_jpeg")||(a_format=="zb_jpg")||(a_format=="inzb_jpeg")) {
if(!a_jpeg_writer) {
a_out << "tools::sg::write_paper : no jpeg_writer given." << std::endl;
return false;
}
size_t sz;
unsigned char* buffer = action.get_rgbs(sz);
if(!buffer) {
a_out << "tools::sg::write_paper : can't get rgb image." << std::endl;
return false;
}
if(!a_jpeg_writer(a_out,a_file,buffer,a_width,a_height,3,100)) {
a_out << "tools::sg::write_paper : tools::jpeg::write() failed." << std::endl;
delete [] buffer;
return false;
}
delete [] buffer;
return true;
}
a_out << "tools::sg::write_paper : unknown format " << a_format << std::endl;
return false;
}
}}
#endif