Commit 025b405d authored by Hans-Christian Ebke's avatar Hans-Christian Ebke

Added bezier polyline functions. (Thanks to Hannes)


git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@17444 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 3946a064
This diff is collapsed.
......@@ -46,6 +46,7 @@
#include <ACG/Scenegraph/GlutPrimitiveNode.hh>
#include <ObjectTypes/PolyLine/PolyLineCircleData.hh>
#include <ObjectTypes/PolyLine/PolyLineBezierSplineData.hh>
#define CREATE_CUT_POLYLINE "Create Polyline"
......@@ -140,6 +141,7 @@ public :
enum EditMode { PL_NONE =0,
PL_INSERT=1,
PL_INSERTCIRCLE,
PL_INSERTSPLINE,
PL_DELETE,
PL_MOVE,
PL_SPLIT,
......@@ -179,6 +181,7 @@ private slots:
void slot_smart_move_timer();
void slot_setCirclePointNum(int i);
void slot_setSplinePointNum(int i);
private :
......@@ -187,6 +190,7 @@ private :
// mouse events
void me_insert ( QMouseEvent* _event );
void me_insertCircle( QMouseEvent* _event );
void me_insertSpline( QMouseEvent* _event );
void me_delete ( QMouseEvent* _event );
void me_move ( QMouseEvent* _event );
void me_split ( QMouseEvent* _event );
......@@ -234,6 +238,7 @@ private :
QAction* insertAction_;
QAction* insertCircleAction_;
QAction* insertSplineAction_;
QAction* deleteAction_;
QAction* moveAction_;
QAction* smartMoveAction_;
......@@ -304,66 +309,103 @@ private:
ACG::SceneGraph::GlutPrimitiveNode* moveCircle_SelNode_;
/**
* \brief Calculates a point on the mesh.
*
* Finds the nearest point on the mesh given a point on the normal plane
*
* @param _triMeshObject The mesh to use
* @param _center The center of the ellipse
* @param _pOnPlane The projection of the hit point on the plane
* @param _n The normal of the ellipse
* @param _pOut The point on the mesh if one could be found.
* @return True if a point could be found.
*/
bool createCircle_getPointOnMesh(TriMeshObject* _triMeshObject,
ACG::Vec3d _center,
ACG::Vec3d _pOnPlane,
ACG::Vec3d _n,
ACG::Vec3d* _pOut);
/*
* \brief Calculates common info.
*
* Calculates common info like point on the mesh, point on the normal plane and the distance from the circle center
*
* @param _circleData The circle to use.
* @param _hit_Point The point which to "project".
* @param _pOut (optional)Point on the mesh.
* @param _r The distance between circle center and point on the plane.
* @param _onPlane Point on the normal plane regarding the hit_point.
*/
bool createCircle_getHitInfo(PolyLineCircleData* _circleData,
ACG::Vec3d _hit_Point,
ACG::Vec3d* _pOut = 0,
double* _r = 0,
ACG::Vec3d* _onPlane = 0);
/** \brief Returns point on mesh or point on the normal plane.
*
* Helper function which returns the point on the mesh or if none could be found the point on the plane
*
* @param _circleData The circle to use.
* @param _hit_point The point to "project".
*
* @return Point on the mesh if one was found or on the normal plane.
*/
ACG::Vec3d createCircle_getHit(PolyLineCircleData* _circleData, ACG::Vec3d _hit_point);
/*
* \brief Generates points for the ellipse.
*
* @param _lineObject The object to generate points for.
* @param _pointCount The number of points to generate.
*
*/
void updatePolyEllipse(PolyLineObject* _lineObject, unsigned int _pointCount);
/*
* \brief Updates the center, forward and side handle of the Poly ellipse
*
* @param _lineObject The object containing the handles.
*/
void updateHandles(PolyLineObject* _lineObject);
* \brief Calculates a point on the mesh.
*
* Finds the nearest point on the mesh given a point on the normal plane
*
* @param _triMeshObject The mesh to use
* @param _center The center of the ellipse
* @param _pOnPlane The projection of the hit point on the plane
* @param _n The normal of the ellipse
* @param _pOut The point on the mesh if one could be found.
* @return True if a point could be found.
*/
bool createCircle_getPointOnMesh(TriMeshObject* _triMeshObject,
ACG::Vec3d _center,
ACG::Vec3d _pOnPlane,
ACG::Vec3d _n,
ACG::Vec3d* _pOut);
/*
* \brief Calculates common info.
*
* Calculates common info like point on the mesh, point on the normal plane and the distance from the circle center
*
* @param _circleData The circle to use.
* @param _hit_Point The point which to "project".
* @param _pOut (optional)Point on the mesh.
* @param _r The distance between circle center and point on the plane.
* @param _onPlane Point on the normal plane regarding the hit_point.
*/
bool createCircle_getHitInfo(PolyLineCircleData* _circleData,
ACG::Vec3d _hit_Point,
ACG::Vec3d* _pOut = 0,
double* _r = 0,
ACG::Vec3d* _onPlane = 0);
/** \brief Returns point on mesh or point on the normal plane.
*
* Helper function which returns the point on the mesh or if none could be found the point on the plane
*
* @param _circleData The circle to use.
* @param _hit_point The point to "project".
*
* @return Point on the mesh if one was found or on the normal plane.
*/
ACG::Vec3d createCircle_getHit(PolyLineCircleData* _circleData, ACG::Vec3d _hit_point);
/*
* \brief Generates points for the ellipse.
*
* @param _lineObject The object to generate points for.
* @param _pointCount The number of points to generate.
*
*/
void updatePolyEllipse(PolyLineObject* _lineObject, unsigned int _pointCount);
/*
* \brief Updates the center, forward and side handle of the Poly ellipse
*
* @param _lineObject The object containing the handles.
*/
void updateHandles(PolyLineObject* _lineObject);
/*
* \brief Generates points for the spline, updates handles.
*
* @param _lineObject The object to generate points for.
* @param _pointCount The number of points to generate.
*
*/
void updatePolyBezierSpline(PolyLineObject* _lineObject, unsigned int _pointsPerSegment);
/*
* \brief Updates all the handles on the PolyBezier
* @param _lineObject The object to update.
* @param _line the line node containing all the handles
*/
void updatePolyBezierHandles(PolyLineObject* _lineObject, ACG::SceneGraph::LineNode* _line);
/*
* \brief Returns the nearest point on the mesh or if none could be found the input.
*
* @param _SplineData The spline which is being used.
* @param _point The input point.
* @param _nor (Optional)Normal at nearest point.
* @return The nearest point on the mesh from _point
*/
ACG::Vec3d getPointOnMesh(PolyLineBezierSplineData* _SplineData, ACG::Vec3d _point, ACG::Vec3d* _nor = 0);
/// The index of the currently created spline.
int createSpline_CurrSelIndex_;
/// Use this one to mark the last index to update the number of points
int createSpline_LastSelIndex_;
/// The handle which is being dragged.
ACG::SceneGraph::GlutPrimitiveNode* moveBezSpline_SelNode_;
/// The object which is being moved
int moveBezSpline_SelIndex_;
/// The index of the control or handle being moved
int moveBezSpline_SelSubIndex_;
int cur_merge_id_;
......
/*===========================================================================*\
* *
* 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: 17392 $ *
* $Author: moebius $ *
* $Date: 2013-08-26 15:03:53 +0200 (Mon, 26 Aug 2013) $ *
* *
\*===========================================================================*/
//=============================================================================
//
// CLASS PolyLinePlugin - IMPLEMENTATION
//
//=============================================================================
//== INCLUDES =================================================================
#include "PolyLinePlugin.hh"
ACG::Vec3d
PolyLinePlugin::
getPointOnMesh(PolyLineBezierSplineData* _SplineData, ACG::Vec3d _point, ACG::Vec3d* _nor)
{
TriMeshObject* mesh;
if(!PluginFunctions::getObject(_SplineData->MeshIndex_, mesh))
return _point;
OpenMeshTriangleBSPT<TriMesh>* bsp = mesh->requestTriangleBsp();
OpenMeshTriangleBSPT<TriMesh>::NearestNeighbor neigh = bsp->nearest(_point);
ACG::Vec3d nor = mesh->mesh()->normal(neigh.handle);
if(_nor)
*_nor = nor;
OpenMeshTriangleBSPT<TriMesh>::RayCollision rayInt = bsp->raycollision(_point, nor);
if(rayInt.size())
return _point + nor * rayInt[0].second;
return _point + nor.normalize() * neigh.dist;
}
void
PolyLinePlugin::
updatePolyBezierHandles(PolyLineObject* _lineObject, ACG::SceneGraph::LineNode* _line)
{
PolyLineBezierSplineData* splineData = dynamic_cast<PolyLineBezierSplineData*>(_lineObject->objectData(BEZSPLINE_DATA));
if(!splineData)
return;
_line->clear();
for(unsigned int i = 0; i < splineData->Handles_.size(); i++) {
ACG::SceneGraph::GlutPrimitiveNode* node = 0;
if(_lineObject->getAdditionalNode(node, name(), "handle", i))
node->set_position(splineData->Handles_[i]);
const PolyLineBezierSplineData::InterpolatePoint& control = splineData->getInterpolatePoint(i);
_line->add_line(control.Pos_, splineData->Handles_[i]);
_line->add_color(ACG::Vec4f(1,0,0,1));
}
for(unsigned int i = 0; i < splineData->Points_.size(); i++) {
ACG::SceneGraph::GlutPrimitiveNode* node = 0;
if(_lineObject->getAdditionalNode(node, name(), "control", i))
node->set_position(splineData->Points_[i].Pos_);
}
}
void
PolyLinePlugin::
updatePolyBezierSpline(PolyLineObject* _lineObject, unsigned int _pointCount)
{
PolyLineBezierSplineData* splineData = dynamic_cast<PolyLineBezierSplineData*>(_lineObject->objectData(BEZSPLINE_DATA));
if(!splineData)
return;
_lineObject->line()->clear();
int segCount = (splineData->Points_.size() + splineData->Handles_.size() - 1) / 3, segment = 0;
for(int s = 0; s < segCount; s++) {
const ACG::Vec3d a = splineData->Points_[s].Pos_, d = splineData->Points_[s + 1].Pos_,
b = splineData->Handles_[s * 2], c = splineData->Handles_[s * 2 + 1];
for(unsigned int i = 0; i < _pointCount; i++) {
float alpha = float(i) / float(_pointCount);
const ACG::Vec3d e = a + (b - a) * alpha, f = c + (d - c) * alpha;
ACG::Vec3d g = e + (f - e) * alpha;
g = getPointOnMesh(splineData, g);
_lineObject->line()->add_point(g);
}
}
emit updatedObject(_lineObject->id(), UPDATE_GEOMETRY | UPDATE_TOPOLOGY);
}
......@@ -164,14 +164,5 @@ updatePolyEllipse(PolyLineObject* _lineObject, unsigned int _pointCount)
//-----------------------------------------------------------------------------
void
PolyLinePlugin::
slot_setCirclePointNum(int i)
{
PolyLineObject* _lineObject;
if(createCircle_LastSelIndex_ != -1 && PluginFunctions::getObject(createCircle_LastSelIndex_, _lineObject))
updatePolyEllipse(_lineObject, i);
}
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>363</width>
<height>741</height>
<width>364</width>
<height>821</height>
</rect>
</property>
<property name="sizePolicy">
......@@ -92,6 +92,13 @@
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rb_InsertSpline">
<property name="text">
<string>RadioButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
......@@ -553,6 +560,27 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Points per Segment</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sb_SplineSegNum">
<property name="value">
<number>8</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment