Developer Documentation
PolyLinePlugin_Circle.cc
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42/*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Author$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50//=============================================================================
51//
52// CLASS PolyLinePlugin - IMPLEMENTATION
53//
54//=============================================================================
55
56//== INCLUDES =================================================================
57#include "PolyLinePlugin.hh"
58
59namespace {
60
61struct Onb {
62
63 ACG::Vec3d x, y, z;
64
65 explicit Onb(PolyLineCircleData* _circleData):
66 x(_circleData->circleMainAxis_),
67 y(_circleData->circleNormal_),
68 z(_circleData->circleSideAxis_)
69
70 {
71 }
72
73 ACG::Vec3d toWorld(ACG::Vec3d v) const {
74 return ACG::Vec3d(
75 x[0] * v[0] + y[0] * v[1] + z[0] * v[2],
76 x[1] * v[0] + y[1] * v[1] + z[1] * v[2],
77 x[2] * v[0] + y[2] * v[1] + z[2] * v[2]);
78 }
79};
80
81}
82
83//-----------------------------------------------------------------------------
84
86 ACG::Vec3d _pOnPlane, ACG::Vec3d _n, ACG::Vec3d* _pOut) {
89 rayInt = bsp->raycollision(_pOnPlane, _n);
90
91 if (rayInt.empty())
92 return false;
93 int i = -1;
94 double smDist = 10e10;
95
96 for (unsigned int j = 0; j < rayInt.size(); j++) {
97 ACG::Vec3d p = _pOnPlane + _n * rayInt[j].second, dir = _center - p;
98 const double dist = dir.norm();
99 if (dist < smDist) {
100 smDist = dist;
101 if (_pOut)
102 *_pOut = p; //+ norAtInt * 0.002;//that would fix lines below the surface, but what is the correct scale?
103 i = j;
104 }
105 }
106
107 return i != -1;
108}
109
110//-----------------------------------------------------------------------------
111
113 double* r, ACG::Vec3d* _onPlaneO) {
114 ACG::Vec3d n = _circleData->circleNormal_, x0 = _circleData->circleCenter_;
115 double t = ((n | x0) - (n | _hit_Point)) / n.sqrnorm();
116 ACG::Vec3d onPlane = _hit_Point + t * n, d = onPlane - x0;
117 if (r)
118 *r = d.norm();
119 if (_onPlaneO)
120 *_onPlaneO = onPlane;
121 TriMeshObject* mesh;
122 if (PluginFunctions::getObject(_circleData->circleMeshIndex_, mesh))
123 return createCircle_getPointOnMesh(mesh, x0, onPlane, n, _pOut);
124 else
125 return false;
126}
127
128//-----------------------------------------------------------------------------
129
131 ACG::Vec3d pOnMesh, pOnPlane;
132 double r;
133 if (!createCircle_getHitInfo(_circleData, _hit_point, &pOnMesh, &r, &pOnPlane))
134 return pOnPlane; //no point on the mesh was found...
135 else
136 return pOnMesh;
137}
138
139//-----------------------------------------------------------------------------
140
141void PolyLinePlugin::updatePolyEllipse(PolyLineObject* _lineObject, unsigned int _pointCount) {
142 PolyLineCircleData* lineData = dynamic_cast<PolyLineCircleData*>(_lineObject->objectData(CIRCLE_DATA));
143
144 TriMeshObject* mesh;
145 if(!PluginFunctions::getObject(lineData->circleMeshIndex_, mesh))
146 return;//if there is no mesh available do not try to recreate the circle
147
148 const double theta = 2.0 * M_PI / double(_pointCount);
149 // _pointCount += tool_->rb_CloseCircle->isChecked() ? 0 : -1;
150 const double r2 = lineData->circleMainRadius_, r1 = lineData->circleSideRadius_;
151 const Onb basis(lineData);
152
153 _lineObject->line()->clear();
154 _lineObject->line()->set_closed(tool_->rb_CloseCircle->isChecked());
155
156 for (unsigned int i = 0; i <= _pointCount; i++) {
157 const double tanTheta_i = tan(theta * i);
158 double x = (r1 * r2) / sqrt(r2 * r2 + r1 * r1 * tanTheta_i * tanTheta_i);
159 x = ((theta * i) <= M_PI_2 || (theta * i) > (3.0 * M_PI_2)) ? x : -x;
160 const double y = tanTheta_i * x;
161 ACG::Vec3d pOnMesh;
162 const ACG::Vec3d pOnPlane(y, 0, x), //this is in the local coord system!
163 pInWorld = basis.toWorld(pOnPlane) + lineData->circleCenter_;
164 if(moveCircle_IsFloating)
165 _lineObject->line()->add_point(pInWorld);
166 else if(createCircle_getHitInfo(lineData, pInWorld, &pOnMesh))
167 _lineObject->line()->add_point(pOnMesh);
168 }
169
170 emit updatedObject(_lineObject->id(), UPDATE_GEOMETRY | UPDATE_TOPOLOGY);
171}
172
173//-----------------------------------------------------------------------------
174
void set_closed(const bool _c)
Set if the polyline should be closed and therefore forms a loop.
Definition: PolyLineT.hh:116
void clear()
Clear the current polyline.
void add_point(const Point &_p)
Append a point to the polyline.
std::vector< std::pair< Handle, Scalar > > RayCollision
Store nearest neighbor information.
Definition: BSPImplT.hh:95
RayCollision raycollision(const Point &_p, const Point &_r) const
intersect mesh with ray
PerObjectData * objectData(QString _dataName)
Returns the object data pointer.
Definition: BaseObject.cc:801
int id() const
Definition: BaseObject.cc:188
OMTriangleBSP * requestTriangleBsp()
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
Definition: Vector11T.hh:422
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM > >().sqrnorm()))
compute euclidean norm
Definition: Vector11T.hh:434
PolyLine * line()
return a pointer to the line
bool createCircle_getPointOnMesh(TriMeshObject *_triMeshObject, ACG::Vec3d _center, ACG::Vec3d _pOnPlane, ACG::Vec3d _n, ACG::Vec3d *_pOut)
Calculates a point on the mesh.
ACG::Vec3d createCircle_getHit(PolyLineCircleData *_circleData, ACG::Vec3d _hit_point)
Returns point on mesh or point on the normal plane.
PolyLineToolbarWidget * tool_
Widget for Toolbox.
bool createCircle_getHitInfo(PolyLineCircleData *_circleData, ACG::Vec3d _hit_Point, ACG::Vec3d *_pOut=0, double *_r=0, ACG::Vec3d *_onPlane=0)
Calculates common info.
void updatePolyEllipse(PolyLineObject *_lineObject, unsigned int _pointCount)
Generates points for the ellipse.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(8))
Topology updated.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.