Re: [osg-users] Update node color on demand

2018-11-26 Thread Trajce Nikolov NICK
Hi,

try in void ColorVisitor::apply(osg::Geode ) {
.
if (colorArrays) {
for (unsigned int i = 0; i < colorArrays->size(); i++)
{
osg::Vec4 *color = >operator [](i);
//
// could also use *color = m_color
//
color->set(m_color._v[0], m_color._v[1], m_color._v[2],
m_color._v[3]);
}
colorArrays->dirty() or ->dirtyBufferObject() I am not sure what was the
right call. Please look it up. It is not enough only to change the color,
you have to dirty the array to be updated
}

On Tue, Nov 27, 2018 at 2:10 AM Diego Mancilla  wrote:

> Hello Trajce,
>
>  The visitor class implementation is on my previous post on this thread. I
> took that code from Gordon Tomlison's OSG Samples, and it works when is
> used previous to the rendering as you can see on my initial post (other
> thread: http://forum.openscenegraph.org/viewtopic.php?p=75209#75209).
>
>
>  As I said everything gets called when it should, but on runtime, the
> lines wont change color. I you look at the code snippet of my main:
>
>
>
> Code:
> _lines = osgDB::readNodeFile("lines.dxf");
> _topo->setDataVariance(osg::Object::DYNAMIC);
> osg::Geode* geode = new osg::Geode;
>
> _mViewer->addEventHandler(new ColorHandler);
>
> ColorVisitor newColor;
> newColor.setColor( 1.0f, 0.0f, 0.0f );
> _lines->accept(newColor);
> geode->addChild(_lines);
> _mViewer->realize();
>
>
>
> The color of the lines turns red on start. But then, when I try to change
> it to another color on runetime, nothing happens.
>
> Anyway, here is the visitor implementation (.cpp):
>
>
> Code:
> ColorVisitor::ColorVisitor():
> osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
> {
> m_color.set(1.0, 1.0, 1.0, 1.0);
> m_colorArrays = new osg::Vec4Array;
> m_colorArrays->push_back(m_color);
> };
>
> ColorVisitor::ColorVisitor(const osg::Vec4 ):
> osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
> {
> m_color = color;
> m_colorArrays = new osg::Vec4Array;
> m_colorArrays->push_back(m_color);
>
> };
>
> ColorVisitor::~ColorVisitor()
> {
> };
>
> void ColorVisitor::apply(osg::Node ) {
> // 
> //
> //  Handle traversal of osg::Node node types
> //
> // 
> traverse(node);
> };
>
> void ColorVisitor::apply(osg::Geode ) {
> // 
> //
> //  Handle traversal of osg::Geode node types
> //
> // 
>
> osg::StateSet *state = NULL;
> unsigned intvertNum = 0;
> //
> //  We need to iterate through all the drawables check if
> //  the contain any geometry that we will need to process
> //
>
> unsigned int numGeoms = geode.getNumDrawables();
>
> for (unsigned int geodeIdx = 0; geodeIdx < numGeoms; geodeIdx++)
> {
> //
> // Use 'asGeometry' as its supposed to be faster than a
> dynamic_cast
> // every little saving counts
> //
> osg::Geometry *curGeom =
> geode.getDrawable(geodeIdx)->asGeometry();
> //
> // Only process if the drawable is geometry
> //
> if (curGeom)
> {
> osg::Vec4Array *colorArrays = dynamic_cast *>(curGeom->getColorArray());
> if (colorArrays) {
> for (unsigned int i = 0; i < colorArrays->size(); i++)
> {
> osg::Vec4 *color = >operator [](i);
> //
> // could also use *color = m_color
> //
> color->set(m_color._v[0], m_color._v[1],
> m_color._v[2], m_color._v[3]);
> }
>
> }
> else
> {
> curGeom->setColorArray(m_colorArrays.get());
> curGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
> }
> }
> }
> };
>
> void ColorVisitor::setColor(const float r, const float g, const float b,
> const float a)
> {
> // ---
> //
> // Set the color to change apply to the nodes geometry
> //
> // ---
> osg::Vec4 *c = _colorArrays->operator [](0);
> m_color.set(r, g, b, a);
> *c = m_color;
> };
>
> void ColorVisitor::setColor(const osg::Vec4 ) {
> // ---
> //
> // Set the color to change apply to the nodes geometry
> //
> // ---
> osg::Vec4 *c = _colorArrays->operator [](0);
> m_color = color;
> *c = m_color;
> };
>
>
>
>
>
> Cheers,
>
> --
> Read this topic online here:
> 

Re: [osg-users] Update node color on demand

2018-11-26 Thread Diego Mancilla
Hello Trajce,

 The visitor class implementation is on my previous post on this thread. I took 
that code from Gordon Tomlison's OSG Samples, and it works when is used 
previous to the rendering as you can see on my initial post (other thread: 
http://forum.openscenegraph.org/viewtopic.php?p=75209#75209).


 As I said everything gets called when it should, but on runtime, the lines 
wont change color. I you look at the code snippet of my main:

 

Code:
_lines = osgDB::readNodeFile("lines.dxf"); 
_topo->setDataVariance(osg::Object::DYNAMIC); 
osg::Geode* geode = new osg::Geode; 

_mViewer->addEventHandler(new ColorHandler); 

ColorVisitor newColor; 
newColor.setColor( 1.0f, 0.0f, 0.0f ); 
_lines->accept(newColor); 
geode->addChild(_lines); 
_mViewer->realize();



The color of the lines turns red on start. But then, when I try to change it to 
another color on runetime, nothing happens.

Anyway, here is the visitor implementation (.cpp):


Code:
ColorVisitor::ColorVisitor(): 
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) 
{ 
m_color.set(1.0, 1.0, 1.0, 1.0); 
m_colorArrays = new osg::Vec4Array; 
m_colorArrays->push_back(m_color); 
}; 

ColorVisitor::ColorVisitor(const osg::Vec4 ): 
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) 
{ 
m_color = color; 
m_colorArrays = new osg::Vec4Array; 
m_colorArrays->push_back(m_color); 

}; 

ColorVisitor::~ColorVisitor() 
{ 
}; 

void ColorVisitor::apply(osg::Node ) { 
//  
// 
//  Handle traversal of osg::Node node types 
// 
//  
traverse(node); 
}; 

void ColorVisitor::apply(osg::Geode ) { 
//  
// 
//  Handle traversal of osg::Geode node types 
// 
//  

osg::StateSet *state = NULL; 
unsigned intvertNum = 0; 
//  
//  We need to iterate through all the drawables check if 
//  the contain any geometry that we will need to process 
// 

unsigned int numGeoms = geode.getNumDrawables(); 

for (unsigned int geodeIdx = 0; geodeIdx < numGeoms; geodeIdx++) 
{ 
// 
// Use 'asGeometry' as its supposed to be faster than a dynamic_cast 
// every little saving counts 
// 
osg::Geometry *curGeom = geode.getDrawable(geodeIdx)->asGeometry(); 
// 
// Only process if the drawable is geometry 
// 
if (curGeom) 
{ 
osg::Vec4Array *colorArrays = dynamic_cast(curGeom->getColorArray()); 
if (colorArrays) { 
for (unsigned int i = 0; i < colorArrays->size(); i++) 
{ 
osg::Vec4 *color = >operator [](i); 
// 
// could also use *color = m_color 
// 
color->set(m_color._v[0], m_color._v[1], m_color._v[2], 
m_color._v[3]); 
} 

} 
else 
{ 
curGeom->setColorArray(m_colorArrays.get()); 
curGeom->setColorBinding(osg::Geometry::BIND_OVERALL); 
} 
} 
} 
}; 

void ColorVisitor::setColor(const float r, const float g, const float b, const 
float a) 
{ 
// --- 
// 
// Set the color to change apply to the nodes geometry 
// 
// --- 
osg::Vec4 *c = _colorArrays->operator [](0); 
m_color.set(r, g, b, a); 
*c = m_color; 
}; 

void ColorVisitor::setColor(const osg::Vec4 ) { 
// --- 
// 
// Set the color to change apply to the nodes geometry 
// 
// --- 
osg::Vec4 *c = _colorArrays->operator [](0); 
m_color = color; 
*c = m_color; 
};





Cheers,

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75248#75248





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Update node color on demand

2018-11-26 Thread Trajce Nikolov NICK
Hi Diego,

can you post your Visitor code? It can be something like missing calling
->dirty() on the color array or such

On Mon, Nov 26, 2018 at 8:30 PM Diego Mancilla  wrote:

> Hello,
>
> I have tried Eran's suggestion with no success. I have successfully
> created the handler, and it gets called but no color change...
>
> My current code:
>
> On main:
>
> Code:
> _lines = osgDB::readNodeFile("lines.dxf");
> _topo->setDataVariance(osg::Object::DYNAMIC);
> osg::Geode* geode = new osg::Geode;
>
> _mViewer->addEventHandler(new ColorHandler);
>
> ColorVisitor newColor;
> newColor.setColor( 1.0f, 0.0f, 0.0f );
> _lines->accept(newColor);
> geode->addChild(_lines);
> _mViewer->realize();
>
>
>
>
> The handler:
>
>
> Code:
> bool ColorHandler::handle(const osgGA::GUIEventAdapter& ea,
> osgGA::GUIActionAdapter& aa)
> {
> if (ea.getEventType() == ea.USER)
> {
> auto changeColorEvent = dynamic_cast ChangeColorEvent*>(ea.getUserData());
> if (changeColorEvent != nullptr)
> {
> std::cout << "Hola Handler!!!" << std::endl;
> std::cout << "new color: " <<
> changeColorEvent->r<<" "<< changeColorEvent->g<< " "<<
> changeColorEvent->b< ColorVisitor newColor;
> newColor.setColor(changeColorEvent->r,
> changeColorEvent->g, changeColorEvent->b);
> changeColorEvent->node->accept(newColor);
> return true;
> }
> }
> return false;
>
>
>
> Thank you!
>
> Cheers,
> Diego
>
> --
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=75245#75245
>
>
>
>
>
> ___
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>


-- 
trajce nikolov nick
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Update node color on demand

2018-11-26 Thread Diego Mancilla
Hello,

I have tried Eran's suggestion with no success. I have successfully created the 
handler, and it gets called but no color change...

My current code:

On main:

Code:
_lines = osgDB::readNodeFile("lines.dxf");
_topo->setDataVariance(osg::Object::DYNAMIC);
osg::Geode* geode = new osg::Geode;

_mViewer->addEventHandler(new ColorHandler);

ColorVisitor newColor;
newColor.setColor( 1.0f, 0.0f, 0.0f );
_lines->accept(newColor);
geode->addChild(_lines);
_mViewer->realize();




The handler:


Code:
bool ColorHandler::handle(const osgGA::GUIEventAdapter& ea, 
osgGA::GUIActionAdapter& aa)
{
if (ea.getEventType() == ea.USER)
{
auto changeColorEvent = dynamic_cast(ea.getUserData());
if (changeColorEvent != nullptr)
{
std::cout << "Hola Handler!!!" << std::endl;
std::cout << "new color: " << changeColorEvent->r<<" 
"<< changeColorEvent->g<< " "<< changeColorEvent->bg, changeColorEvent->b);
changeColorEvent->node->accept(newColor);
return true;
}
}
return false;



Thank you!

Cheers,
Diego

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75245#75245





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Update node color on demand

2018-11-26 Thread Diego Mancilla
Hello Eran,

 Thank you again.

 I will try what you suggest. 

Cheers,

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75244#75244





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Update node color on demand

2018-11-24 Thread Eran Cohen
Hi Diego,

You can pass user events to the viewer (and thus to its Event Handlers):

Code:

// This struct will be passed to the event handler with the relevant parameters 
(for example, the node you want to affect and the color to change it to)
struct ChangeColorEvent : public osg::Referenced
{
  ChangeColorEvent(float r, float g, float b, osg::Node* node)
  {
this->r = r;
this->g = g;
this->b = b;
this->node = node;
  }

  float r;
  float g;
  float b;
  osg::Node* node;
}

// When you want to call the event (on a button click in QT for example)
viewer->getEventQueue()->userEvent(new ChangeColorEvent{ 1.0, 0.3, 0.4, node }, 
0);




To handle said event in your EventHandler:

Code:

class ColorHandler : public osgGA::GUIEventHandler 
{ 
   virtual bool handle(const osgGA::GUIEventAdapter& ea, 
osgGA::GUIActionAdapter& aa) override 
   { 
  if (ea.getEventType() == ea.USER) 
  { 
 auto changeColorEvent = dynamic_cast(ea.getUserData());
 if (changeColorEvent != nullptr)
 {
   // do whatever you want here, for example run the visitor on the node
   return true;
 }
  } 
  return false;
   } 
}; 





Cheers,
Eran

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75241#75241





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Update node color on demand

2018-11-24 Thread Diego Mancilla
Hello Eran,

 Thank you very much for your answer. I should have been more explicit, due to 
the fact than I'm a newbie on OSG (and 3D development).

 I have an OSG viewer embedded on a Qt5 application. So the idea is that the 
user can change the color of one node (some dxf lines) on demand though the GUI 
(some dialog, pushing buttons, etc). So, bottom line... at some point at 
runtime I have a fresh new color (rgb, for instance) and I need to pass it to 
the viewer towards the "_lines" node. As I previuosly stated I'm new to OSG and 
I'm just digesting the scene graph scheme.

 So, how can I pass this information from the Qt5 environment, to the to the 
node using your suggestions?


Thank you in advance!

Cheers,

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75240#75240





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Update node color on demand

2018-11-24 Thread Eran Cohen
Hi,
To respond to user events you can either inherit from osg::Callback and install 
it on your node as an EventCallback:


Code:

class ColorCallback : public osg::Callback
{
public:
virtual bool run(osg::Object* object, osg::Object* data) override
{
auto nv = dynamic_cast(data);
if (nv != nullptr && nv->getVisitorType() == nv->EVENT_VISITOR)
{
auto events = nv->asEventVisitor()->getEvents();
for (auto event : events)
{
// handle events
}
}

return traverse(object, data);
}
};

_lines->addEventCallback(new ColorCallback);




or use a global EventHandler and install it on your Viewer:

Code:

class ColorHandler : public osgGA::GUIEventHandler
{
virtual bool handle(const osgGA::GUIEventAdapter& ea, 
osgGA::GUIActionAdapter& aa) override
{
if (ea.getEventType() == ea.KEYDOWN)
{
// handle event 
}
}
};


viewer->addEventHandler(new ColorHandler);




Cheers,
Eran

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75239#75239





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


[osg-users] Update node color on demand

2018-11-24 Thread Diego Mancilla
Hello,

I'm trying to change a node color on demand from my application. The idea is 
that the user, once the initial rendering took place can change the color of a 
node by pressing a key (or something similar). I know already hoy to change the 
color using a NodeVisitor (previous to the rendering). 


Code:
ColorVisitor newColor;
newColor.setColor(r, g, b);
_lines->accept(newColor);



Where _lines is a Node reference pointer and ColorVisitor is a subclass of 
NodeVisitor (http://forum.openscenegraph.org/viewtopic.php?p=75209#75209).

I tried to create a callback and attach it to the node but the callback get 
called every time and I cant pass to it the selected color on runtime.

Can anyone give some pointer about this issue?

Thank you!

Cheers,
[/url]

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75238#75238





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org