Commit abed76f1 authored by Jan Möbius's avatar Jan Möbius

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14861 383ad7c9-94d9-4d36-a494-682f7c89f535
parent c6b66372
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision$
// $Author$
// $Date$
//
//=============================================================================
//=============================================================================
//
// Plugin Functions for PolyLines
//
//=============================================================================
#include <OpenFlipper/common/Types.hh>
#include "PolyLine.hh"
#include "PluginFunctionsPolyLine.hh"
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
namespace PluginFunctions {
// ===============================================================================
// Get source polylines
// ===============================================================================
bool getSourcePolylines( std::vector<PolyLine*>& _polylines )
{
_polylines.clear();
for ( ObjectIterator o_it(PluginFunctions::SOURCE_OBJECTS,DATA_POLY_LINE ) ;
o_it != PluginFunctions::objectsEnd(); ++o_it) {
_polylines.push_back ( PluginFunctions::polyLine( *o_it ) );
if( _polylines.back() == 0)
std::cerr << "ERROR: Polyine get_source_polylines fatal error\n";
}
return (_polylines.size() > 0 );
}
// ===============================================================================
// Get target polylines
// ===============================================================================
bool getTargetPolylines( std::vector<PolyLine*>& _polylines )
{
_polylines.clear();
for ( ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,DATA_POLY_LINE ) ;
o_it != PluginFunctions::objectsEnd(); ++o_it) {
_polylines.push_back ( PluginFunctions::polyLine( *o_it ) );
if( _polylines.back() == 0)
std::cerr << "ERROR: Polyine getTargetPolylines fatal error\n";
}
return (_polylines.size() > 0 );
}
// ===============================================================================
// Get objects
// ===============================================================================
bool getObject( int _identifier , PolyLineObject*& _object ) {
if ( _identifier == -1 ) {
_object = 0;
return false;
}
BaseObject* object = objectRoot()->childExists( _identifier );
_object = dynamic_cast< PolyLineObject* >(object);
return ( _object != 0 );
}
// ===============================================================================
// Getting data from objects and casting between them
// ===============================================================================
PolyLine* polyLine( BaseObjectData* _object ) {
if ( _object->dataType(DATA_POLY_LINE) ) {
PolyLineObject* object = dynamic_cast< PolyLineObject* >(_object);
return object->line();
} else
return 0;
}
PolyLineObject* polyLineObject( BaseObjectData* _object ) {
if ( ! _object->dataType(DATA_POLY_LINE) )
return 0;
return dynamic_cast< PolyLineObject* >( _object );
}
PolyLineObject* polyLineObject( int _objectId ) {
if (_objectId == -1)
return 0;
BaseObject* object = objectRoot()->childExists( _objectId );
if ( object == 0 )
return 0;
PolyLineObject* meshObject = dynamic_cast< PolyLineObject* >(object);
return meshObject;
}
}
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision$
// $Author$
// $Date$
//
//=============================================================================
//=============================================================================
//
// Standard Functions
//
//=============================================================================
/**
* \file PluginFunctionsPolyLine.hh
* This file contains functions which can be used by plugins to access polylines in the framework.
*/
//
#ifndef PLUGINFUNCTIONSPOLYLINE_HH
#define PLUGINFUNCTIONSPOLYLINE_HH
#include <OpenFlipper/common/Types.hh>
/** The Namespace PluginFunctions contains functions for all plugins. */
namespace PluginFunctions {
/** \brief Get a pointer to every Polyline which is marked as a source.
*
* @param _polylines ( vector returning the source polylines )
* @return false, if no polyline is selected as source
*/
DLLEXPORT
bool getSourcePolylines( std::vector<PolyLine*>& _polylines );
/** \brief Get a pointer to every Polyline which is marked as a target.
*
* @param _polylines ( vector returning the target polylines )
* @return false, if no polyline is selected as target
*/
DLLEXPORT
bool getTargetPolylines( std::vector<PolyLine*>& _polylines );
/** This functions returns the object with the given id if it is a PolyLineObject.
* See get_object( int _identifier , BaseObject*& _object ) for more details.
*/
DLLEXPORT
bool getObject( int _identifier , PolyLineObject*& _object );
/** \brief Get a poly Line from an object.
*
* @param _object The object should be of type BaseDataObject. If the content is a poly Line, a
* poly line will be returned. Otherwise a NULL pointer is returned.
*/
DLLEXPORT
PolyLine* polyLine( BaseObjectData* _object );
/** \brief Cast an BaseObject to a PolyLineObject if possible
*
* @param _object The object should be of type BaseDataObject. If the content is a polyLine, a
* a PolyLineObject is returned. Otherwise a NULL pointer is returned.
*/
DLLEXPORT
PolyLineObject* polyLineObject( BaseObjectData* _object );
/** \brief Get an PolyLineObject from the given id If possible
*
* @param _objectId Id of the requested Object. If the content is a volume, a
* a PolyLineObject is returned. Otherwise a NULL pointer is returned.
*/
DLLEXPORT
PolyLineObject* polyLineObject( int _objectId );
}
#endif // PLUGINFUNCTIONSPOLYLINE_HH
//=============================================================================
//
// PolyMeshTypes
//
//=============================================================================
/**
* \file PolyLine.hh
* This File contains all required includes for using Poly Lines
*/
#ifndef POLYLINE_INCLUDE_HH
#define POLYLINE_INCLUDE_HH
//== INCLUDES =================================================================
/** \def DATA_POLY_LINE
* Use this macro to reference polygonal lines
*/
#define DATA_POLY_LINE typeId("PolyLine")
#include <ObjectTypes/PolyLine/PolyLineT.hh>
#include <ObjectTypes/PolyLine/PolyLineObject.hh>
#include <ObjectTypes/PolyLine/PluginFunctionsPolyLine.hh>
#include <ObjectTypes/PolyLine/PolyLineTypes.hh>
//=============================================================================
#endif // POLYLINE_INCLUDE_HH defined
//=============================================================================
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Author$ *
* $Date$ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS PolyLineNodeT - IMPLEMENTATION
//
//=============================================================================
#define ACG_POLYLINENODET_C
//== INCLUDES =================================================================
#include "PolyLineNodeT.hh"
#include <ACG/GL/gl.hh>
#include <ACG/Utils/VSToolsT.hh>
#include <vector>
//== NAMESPACES ===============================================================
namespace ACG {
namespace SceneGraph {
//== IMPLEMENTATION ==========================================================
template <class PolyLine>
void
PolyLineNodeT<PolyLine>::
boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
{
for (unsigned int i=0; i< polyline_.n_vertices(); ++i)
{
_bbMin.minimize(polyline_.point(i));
_bbMax.maximize(polyline_.point(i));
}
}
//----------------------------------------------------------------------------
template <class PolyLine>
DrawModes::DrawMode
PolyLineNodeT<PolyLine>::
availableDrawModes()
{
return (DrawModes::WIREFRAME | DrawModes::POINTS);
}
//----------------------------------------------------------------------------
template <class PolyLine>
void
PolyLineNodeT<PolyLine>::
draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
{
// Block if we do not have any vertices
if ( polyline_.n_vertices() == 0 )
return;
ACG::GLState::disable(GL_LIGHTING);
ACG::GLState::disable(GL_TEXTURE_2D);
// Bind the vertex array
ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
ACG::GLState::vertexPointer( &(polyline_.points())[0] );
ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
ACG::GLState::disableClientState(GL_COLOR_ARRAY);
// draw points
if (_drawMode & DrawModes::POINTS)
{
// draw selection
if( polyline_.vertex_selections_available())
{
// save old values
Vec4f base_color_old = _state.base_color();
float point_size_old = _state.point_size();
_state.set_base_color(Vec4f(1,0,0,1));
_state.set_point_size(point_size_old+4);
glBegin(GL_POINTS);
for (unsigned int i=0; i< polyline_.n_vertices(); ++i)
if( polyline_.vertex_selection(i))
glArrayElement(i);
glEnd();
_state.set_base_color(base_color_old);
_state.set_point_size(point_size_old);
}
// Draw all vertices (don't care about selection
glDrawArrays(GL_POINTS,0,polyline_.n_vertices());
}
// draw line segments
if (_drawMode & DrawModes::WIREFRAME)
{
// draw selection
if( polyline_.edge_selections_available())
{
// save old values
Vec4f base_color_old = _state.base_color();
float line_width_old = _state.line_width();
_state.set_base_color(Vec4f(1,0,0,1));
_state.set_line_width(2*line_width_old);
glBegin(GL_LINES);
// draw possibly closed PolyLine
for (unsigned int i=0; i< polyline_.n_edges(); ++i)
{
if( polyline_.edge_selection(i))
{
glArrayElement( i % polyline_.n_vertices() );
glArrayElement( (i+1) % polyline_.n_vertices() );
}
}
glEnd();
_state.set_base_color(base_color_old);
_state.set_line_width(line_width_old);
}
// draw all line segments
glBegin(GL_LINE_STRIP);
// draw possibly closed PolyLine
if( polyline_.n_vertices())
glArrayElement(0);
for (unsigned int i=0; i< polyline_.n_edges(); ++i)
glArrayElement( (i+1) % polyline_.n_vertices() );
glEnd();
}
// draw normals
if (polyline_.vertex_normals_available())
{
double avg_len = polyline_.n_edges() > 0 ? (polyline_.length() / polyline_.n_edges() * 0.75) : 0;
std::vector<Point> ps;
for (unsigned int i=0; i< polyline_.n_vertices(); ++i)
{
ps.push_back(polyline_.point(i));
ps.push_back(polyline_.point(i)+polyline_.vertex_normal(i)*avg_len);
if(polyline_.vertex_binormals_available())
ps.push_back(polyline_.point(i)+polyline_.vertex_binormal(i)*avg_len);
}
ACG::GLState::vertexPointer( &ps[0] );
Vec4f base_color_old = _state.base_color();
float line_width_old = _state.line_width();
_state.set_base_color(Vec4f(0.8,0,0,1));
_state.set_line_width(1);
int stride = polyline_.vertex_binormals_available() ? 3 : 2;
glBegin(GL_LINES);
for (unsigned int i=0; i< polyline_.n_vertices(); ++i)
{
glArrayElement( stride*i );
glArrayElement( stride*i+1 );
}
glEnd();
if (polyline_.vertex_binormals_available())
{
_state.set_base_color(Vec4f(0,0,0.8,1));
glBegin(GL_LINES);
for (unsigned int i=0; i< polyline_.n_vertices(); ++i)
{
glArrayElement( stride*i );
glArrayElement( stride*i+2 );
}
glEnd();
}
_state.set_base_color(base_color_old);
_state.set_line_width(line_width_old);
}
//Disable the vertex array
ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
}
//----------------------------------------------------------------------------
template <class PolyLine>
void
PolyLineNodeT<PolyLine>::
pick(GLState& _state, PickTarget _target)
{
if ( polyline_.n_vertices() == 0 )
return;
// Bind the vertex array
ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
ACG::GLState::vertexPointer( &(polyline_.points())[0] );
ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
unsigned int n_end = polyline_.n_edges()+1;
if( !polyline_.is_closed()) --n_end;
// (draw lines slightly in front of everything else)
//disabled right now because of rendering artifacts.
//This probably doesn't make sense anyways since the lines are drawn as cylinders and therefore have a width
// glDepthRange(0.0,0.99)
switch (_target)
{
case PICK_VERTEX:
{
_state.pick_set_maximum (polyline_.n_vertices());
pick_vertices( _state);
break;
}
case PICK_EDGE:
{
_state.pick_set_maximum (n_end);
pick_edges(_state, 0);
break;
}
case PICK_ANYTHING:
{
_state.pick_set_maximum (polyline_.n_vertices() + n_end);
pick_vertices( _state);
pick_edges( _state, polyline_.n_vertices());
break;
}
default:
break;
}
//see above
// glDepthRange(0.0,1.0)
//Disable the vertex array
ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
}
//----------------------------------------------------------------------------
template <class PolyLine>
void
PolyLineNodeT<PolyLine>::
pick_vertices( GLState& _state )
{
float point_size_old = _state.point_size();
glPointSize(18);
_state.pick_set_name(0);
glDepthRange(0.0, 0.999999);
for (unsigned int i=0; i< polyline_.n_vertices(); ++i) {
_state.pick_set_name (i);
glBegin(GL_POINTS);
glArrayElement( i );
glEnd();
}
glDepthRange(0.0, 1.0);
glPointSize(point_size_old);
}
//----------------------------------------------------------------------------
template <class PolyLine>
void
PolyLineNodeT<PolyLine>::
pick_edges( GLState& _state, unsigned int _offset)
{
// Check if we have any edges to draw ( % 0 causes division by zero on windows)
if ( polyline_.n_edges() == 0 )
return;
// save old values
float line_width_old = _state.line_width();
// _state.set_line_width(2*line_width_old);
_state.set_line_width(14);