Commit 8775f4c1 authored by Jan Möbius's avatar Jan Möbius

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14889 383ad7c9-94d9-4d36-a494-682f7c89f535
parents
include (plugin)
if ( WIN32 )
# Do not use frounding flag
else ( WIN32 )
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -frounding-math")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -frounding-math")
endif ( WIN32 )
if (EXISTS ${CMAKE_SOURCE_DIR}/libs/PhySim)
add_definitions (-DUSE_PHYSIM)
FIND_PACKAGE( Boost 1.42.0 COMPONENTS system filesystem regex )
openflipper_plugin (LICENSEMANAGER
DIRS
DEPS Qwt5 CGAL PhySim CoMISo GMP Boost
OPTDEPS Taucs
INSTALLDATA Icons
LIBRARIES
${Boost_LIBRARIES}
)
else()
openflipper_plugin ( LICENSEMANAGER
INSTALLDATA Icons )
endif ()
This diff is collapsed.
This diff is collapsed.
//=============================================================================
//
// CLASS PolyLinePlugin
//
// Author: David Bommes <bommes@cs.rwth-aachen.de>
//
// Version: $Revision: 1$
// Date: $Author$
// $Date: 03-10-2007$
//
//
//=============================================================================
#ifndef POLYLINEPLUGIN_HH
#define POLYLINEPLUGIN_HH
#define CGAL_NO_AUTOLINK_MPFR
#define CGAL_NO_AUTOLINK_GMP
//== INCLUDES =================================================================
#include <QObject>
#include <QMenuBar>
#include <QTimer>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/BasePlugin/MouseInterface.hh>
#include <OpenFlipper/BasePlugin/PickingInterface.hh>
#include <OpenFlipper/BasePlugin/ToolboxInterface.hh>
#include <OpenFlipper/BasePlugin/BackupInterface.hh>
#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
#include <OpenFlipper/BasePlugin/ToolbarInterface.hh>
#include <OpenFlipper/BasePlugin/LoadSaveInterface.hh>
#include <OpenFlipper/BasePlugin/ScriptInterface.hh>
#include <OpenFlipper/common/Types.hh>
#include <ObjectTypes/PolyLine/PolyLine.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include <OpenFlipper/LicenseManager/LicenseManager.hh>
#include "PolyLineToolbarWidget.hh"
#include "QtPlaneSelect.hh"
#define CREATE_CUT_POLYLINE "Create Polyline"
//== CLASS DEFINITION =========================================================
/** Plugin for PolyLine Support
*/
class PolyLinePlugin : public LicenseManager, BaseInterface, MouseInterface,
PickingInterface, ToolboxInterface, LoggingInterface, LoadSaveInterface, ToolbarInterface, ScriptInterface
{
Q_OBJECT
Q_INTERFACES(BaseInterface)
Q_INTERFACES(MouseInterface)
Q_INTERFACES(PickingInterface)
Q_INTERFACES(ToolboxInterface)
Q_INTERFACES(LoggingInterface)
Q_INTERFACES(LoadSaveInterface)
Q_INTERFACES(ToolbarInterface)
Q_INTERFACES(ScriptInterface)
signals:
// BaseInterface
void updateView();
// void updatedObject(int);
void updatedObject(int _id, const UpdateType _type = UPDATE_ALL);
// PickingInterface
void addPickMode( const std::string& _mode );
void addHiddenPickMode( const std::string& _mode );
void setPickModeToolbar (const std::string& _mode, QToolBar * _toolbar);
// LoggingInterface
void log(Logtype _type, QString _message);
void log(QString _message);
// ToolbarInterface
void addToolbar(QToolBar* _toolbar);
void getToolBar( QString _name, QToolBar*& _toolbar);
// ScriptInterface
void scriptInfo( QString _functionName );
// ToolboxInterface
void addToolbox( QString _name , QWidget* _widget );
void deleteObject( int _id );
void addEmptyObject( DataType _type, int& _id);
private slots :
// BaseInterface
void initializePlugin();
void slotEditModeChanged();
void slotMouseEvent( QMouseEvent* _event );
void slotPickModeChanged( const std::string& _mode);
void pluginsInitialized();
public slots :
void slotEnablePickMode(QString _name);
public :
/// Edit Mode of PolyLinePlugin
enum EditMode { PL_NONE =0,
PL_INSERT=1,
PL_DELETE,
PL_MOVE,
PL_SPLIT,
PL_MERGE,
PL_SMART_MOVE };
/// default constructor
PolyLinePlugin();
/// default destructor
~PolyLinePlugin() {};
/// Name of the Plugin
QString name(){ return (QString("PolyLine")); };
/// Description of the Plugin
QString description() { return (QString("Handling of PolyLines (Insertion/Deletion/Modeling/...")); };
private slots:
void slot_subdivide();
void slot_subdivide_percent(bool _checked);
void slot_decimate();
void slot_decimate_percent(bool _checked);
#ifdef EXTENDED_POLY_LINE
void slot_resample_on_edges();
#endif
void slot_smooth();
void slot_smooth( PolyLineObject*& _pol);
void slot_project();
void slot_project( PolyLineObject*& _pol);
void slot_smooth_project();
void slot_smooth_project( PolyLineObject*& _pol);
void slot_smart_move_timer();
private :
EditMode mode();
// mouse events
void me_insert ( QMouseEvent* _event );
void me_delete ( QMouseEvent* _event );
void me_move ( QMouseEvent* _event );
void me_split ( QMouseEvent* _event );
void me_merge ( QMouseEvent* _event );
void me_smart_move( QMouseEvent* _event );
//===========================================================================
/** @name ToolBox
* @{ */
//===========================================================================
private :
/// Widget for Toolbox
PolyLineToolbarWidget* tool_;
/** @} */
//===========================================================================
/** @name ToolBar
* @{ */
//===========================================================================
private :
QAction* polyLineAction_;
QActionGroup* toolBarActions_;
QToolBar* toolbar_;
private slots:
/// Called by Toolbar to enable pick mode
void slotSetPolyLineMode(QAction* _action);
/** @} */
//===========================================================================
/** @name PickToolBar
* @{ */
//===========================================================================
private :
QToolBar* pickToolbar_;
QActionGroup* pickToolBarActions_;
QAction* insertAction_;
QAction* deleteAction_;
QAction* moveAction_;
QAction* smartMoveAction_;
QAction* mergeAction_;
QAction* splitAction_;
QAction* cutAction_;
private slots:
/// Called by pick Toolbar
void slotPickToolbarAction(QAction* _action);
/** @} */
//===========================================================================
/** @name Template Functions
* @{ */
//===========================================================================
private:
/// get the points from the intersection between mesh and plane
template< class MeshT > std::vector< ACG::Vec3d >
getIntersectionPoints ( MeshT* _mesh, uint _fh, ACG::Vec3d _planeNormal ,
ACG::Vec3d _planePoint, bool& _closed );
/// get an edge of the mesh that is cut by the plane
template< class MeshT >
typename MeshT::EdgeHandle
getCuttedEdge(MeshT& _mesh, ACG::Vec3d& _planeNormal, ACG::Vec3d& _planePoint);
/** @} */
public slots:
QString version() { return QString("1.02"); };
//============================================
/// Generates a polyLine of a plane intersection
int generatePolyLineFromCut( int _objectId, Vector _planePoint, Vector _planeNormal, int _polyLineId = -1 );
private slots:
/// Scissor Button was hit
void slotScissorButton();
/// Generate PolyLine after the cutPlane has been drawn
void slotTriggerCutPlaneSelect();
private:
int cur_insert_id_;
PolyLineObject *cur_polyline_obj_;
int cur_move_id_;
PolyLine::Point* move_point_ref_;
PolyLine::Point move_point_orig_;
int cur_merge_id_;
QTimer* smart_move_timer_;
PolyLineObject* cur_smart_move_obj_;
// Plane selection tool
QtPlaneSelect* planeSelect_;
};
#if defined(INCLUDE_TEMPLATES) && !defined(POLYLINEPLUGIN_CC)
#define SCISSORPLUGIN_TEMPLATES
#include "PolyLinePluginT.cc"
#endif
#endif //MOVEPLUGIN_HH
#define POLYLINEPLUGIN_CC
#include "PolyLinePlugin.hh"
//------------------------------------------------------------------------------
/**
*
* @param _mesh the mesh
* @param _fh a starting face that is intersected
* @param _planeNormal normal of the cut plane
* @param _planePoint point on the cut plane
* @param _closed TODO find out what it's good for
* @return a list of intersection points
*/
template< class MeshT >
std::vector< ACG::Vec3d > PolyLinePlugin::getIntersectionPoints( MeshT* _mesh,
uint _fh,
ACG::Vec3d _planeNormal,
ACG::Vec3d _planePoint,
bool& _closed ) {
OpenMesh::HPropHandleT< bool > cut;
_mesh->add_property(cut,"Plane Cut Property" );
typename MeshT::FaceHandle fh ( _fh );
typename MeshT::FaceHandle current_face = typename MeshT::FaceHandle(_fh);
typename MeshT::HalfedgeIter e_it, e_end = _mesh->halfedges_end();
for( e_it = _mesh->halfedges_begin(); e_it != e_end; ++e_it )
_mesh->property( cut, e_it ) = false;
// int id = -1;
bool stop = false;
bool nothingFound = true;
int expansionLevel = 0;
bool flip_dir = false;
_closed = true;
std::vector< ACG::Vec3d > linePoints;
std::vector< typename MeshT::FaceHandle > startCandidates;
std::vector< typename MeshT::FaceHandle > expandable;
expandable.push_back( fh );
while (!stop) {
stop = true;
// First check the face we are in
for ( typename MeshT::FaceHalfedgeIter fhe_it( *_mesh, current_face ); fhe_it; ++fhe_it){
if ( _mesh->property(cut,fhe_it) )
continue;
typename MeshT::Point p0 = _mesh->point( _mesh->from_vertex_handle(fhe_it) );
typename MeshT::Point p1 = _mesh->point( _mesh->to_vertex_handle(fhe_it) );
typename MeshT::Point u = p1 - p0;
typename MeshT::Point w = p0 - _planePoint;
double D = (_planeNormal | u);
double N = - (_planeNormal | w);
// compute intersect param
double sI = N / D;
if (sI < 0.0 || sI > 1.0 ) // intersection on ray, but not within line segment
continue;
nothingFound = false;
stop = false;
_mesh->property(cut,fhe_it.handle()) = true;
_mesh->property(cut,_mesh->opposite_halfedge_handle(fhe_it)) = true;
current_face = _mesh->face_handle(_mesh->opposite_halfedge_handle(fhe_it));
if (!current_face.is_valid())
stop = true;
typename MeshT::Point cutPoint = p0 + sI * u;
// add new point
if ( !flip_dir )
linePoints.push_back(cutPoint);
else {
linePoints.insert( linePoints.begin() , cutPoint );
_closed = false;
}
break;
}
if ( stop ){
if ( nothingFound ){
if ( startCandidates.empty() ){
if (expansionLevel > 3 )
std::cerr << "Expanded" << expansionLevel << "rings but still nothing found!" << std::endl;
else{
//add the "expansionLevel"-ring of the start-face to the start candidates
for (uint i=0; i < expandable.size(); i++)
for( typename MeshT::FaceFaceIter ff_it(*_mesh, expandable[i]); ff_it; ++ff_it )
startCandidates.push_back( ff_it.handle() );
expandable.clear();
expansionLevel++;
}
}
if ( !startCandidates.empty() ){
fh = startCandidates.back();
expandable.push_back( fh );
startCandidates.pop_back();
stop = false;
}
}else if (! flip_dir ){
flip_dir = true;
stop = false;
}
current_face = fh;
}
}
_mesh->remove_property( cut );
return linePoints;
}
//------------------------------------------------------------------------------
/** \brief get an edge of the mesh that is cut by the plane
*
* @param _mesh the mesh
* @param _planeNormal normal of the cut plane
* @param _planePoint point on the cut plane
* @return the edge that is intersected and closest to _planePoint
*/
template< class MeshT >
typename MeshT::EdgeHandle
PolyLinePlugin::getCuttedEdge(MeshT& _mesh, ACG::Vec3d& _planeNormal, ACG::Vec3d& _planePoint) {
typename MeshT::EdgeIter e_it;
typename MeshT::EdgeIter e_end = _mesh.edges_end();
typename MeshT::Scalar minDistance = FLT_MAX;
typename MeshT::EdgeHandle minEdge(-1);
for (e_it = _mesh.edges_begin(); e_it != e_end; ++e_it){
typename MeshT::HalfedgeHandle hh = _mesh.halfedge_handle(e_it, 0);
//get intersection point with plane
typename MeshT::Point p0 = _mesh.point( _mesh.from_vertex_handle(hh) );
typename MeshT::Point p1 = _mesh.point( _mesh.to_vertex_handle(hh) );
typename MeshT::Point u = p1 - p0;
typename MeshT::Point w = p0 - _planePoint;
double D = (_planeNormal | u);
double N = - (_planeNormal | w);
// compute intersect param
double sI = N / D;
if (sI >= 0.0 && sI <= 1.0 ){
typename MeshT::Point cutPoint = p0 + sI * u;
typename MeshT::Scalar dist = (cutPoint - _planePoint).sqrnorm();
if ( dist < minDistance ){
minDistance = dist;
minEdge = e_it.handle();
}
}
}
return minEdge;
}
\ No newline at end of file
#include "PolyLinePlugin.hh"
//------------------------------------------------------------------------------
/** \brief Generates a polyLine of a plane intersection
*
*
* @param _objectId id of the target object
* @param _planePoint a point on the cut plane
* @param _planeNormal the normal of the cut plane
* @param _polyLineId Specify this if you don't want a new polyline to be generated but to reuse an existing one
* @return returns the id of the polyLine
*/
int PolyLinePlugin::generatePolyLineFromCut( int _objectId, Vector _planePoint, Vector _planeNormal, int _polyLineId ) {
// get object
BaseObjectData *obj;
PluginFunctions::getObject(_objectId, obj);
if (obj == 0){
emit log(LOGERR,tr("Unable to get object"));
return -1;
}
//get the intersection points
std::vector< ACG::Vec3d > linePoints;
bool closed = false;
if ( obj->dataType(DATA_TRIANGLE_MESH) ) {
TriMesh* mesh = PluginFunctions::triMesh(obj);
if ( mesh == 0 ) {
emit log(LOGERR,tr("Unable to get mesh"));
return -1;
}
//get an edge of the mesh that is cut by the plane
TriMesh::EdgeHandle eh = getCuttedEdge( *mesh, _planeNormal, _planePoint );
if ( !eh.is_valid() ) {
emit log(LOGERR,tr("Unable to find initial cut edge."));
return -1;
}
TriMesh::FaceHandle fh = mesh->face_handle( mesh->halfedge_handle(eh, 0) );
if (!fh.is_valid())
fh = mesh->face_handle( mesh->halfedge_handle(eh, 1) );
// get all intersection points
linePoints = getIntersectionPoints( mesh, fh.idx() , _planeNormal , _planePoint, closed);
} else {
PolyMesh* mesh = PluginFunctions::polyMesh(obj);
if ( mesh == 0 ) {
emit log(LOGERR,tr("Unable to get mesh"));
return -1;
}
//get a edge of the mesh that is cut by the plane
PolyMesh::EdgeHandle eh = getCuttedEdge( *mesh, _planeNormal, _planePoint );
if ( !eh.is_valid() ) {
emit log(LOGERR,tr("Unable to find initial cut edge."));
return -1;
}
PolyMesh::FaceHandle fh = mesh->face_handle( mesh->halfedge_handle(eh, 0) );
if (!fh.is_valid())
fh = mesh->face_handle( mesh->halfedge_handle(eh, 1) );
// get all intersection points
linePoints = getIntersectionPoints( mesh, fh.idx() , _planeNormal , _planePoint, closed);
}
if ( linePoints.empty() ) {
emit log(LOGERR,tr("No points from cut found."));
return -1;
}
//generate a polyLine from the intersection Points
int polyLineId = -1;
// add new polyline
if (_polyLineId == -1)
emit addEmptyObject(DATA_POLY_LINE,polyLineId);
else
polyLineId = _polyLineId;
// get current polylineobject
BaseObjectData *polyLineObj;
PluginFunctions::getObject(polyLineId, polyLineObj);
// get polyline object
PolyLineObject* currentPolyLine = PluginFunctions::polyLineObject(polyLineObj);
currentPolyLine->line()->clear();
for ( uint i = 0 ; i < linePoints.size(); ++i )
currentPolyLine->line()->add_point( (PolyLine::Point) linePoints[i] );
currentPolyLine->line()->set_closed(closed);
currentPolyLine->target(true);
return polyLineId;
}
#include "PolyLineToolbarWidget.hh"
#include <QtGui>
PolyLineToolbarWidget::PolyLineToolbarWidget(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
#include "ui_polylineToolbar.hh"
#include <QtGui>
class PolyLineToolbarWidget : public QWidget, public Ui::PolyLineToolbar
{
Q_OBJECT
public:
PolyLineToolbarWidget(QWidget *parent = 0);
};
#include "QtPlaneSelect.hh"
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <ACG/Scenegraph/GlutPrimitiveNode.hh>
#define PLUGINFUNCTIONS_C
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <ACG/GL/gl.hh>
#include <ACG/QtWidgets/QtColorTranslator.hh>
#include <QEvent>
#include <QMouseEvent>
/*******************************************************************************
Initialization and de initialization
*******************************************************************************/
QtPlaneSelect::QtPlaneSelect( ACG::GLState& glState )
: glState( glState ),