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 
59 namespace {
60 
61 struct Onb {
62 
63  ACG::Vec3d x, y, z;
64 
65  Onb(PolyLineCircleData* _circleData) {
66  x = _circleData->circleMainAxis_;
67  z = _circleData->circleSideAxis_;
68  y = _circleData->circleNormal_;
69  }
70  ACG::Vec3d toWorld(ACG::Vec3d v) const {
71  return ACG::Vec3d(
72  x[0] * v[0] + y[0] * v[1] + z[0] * v[2],
73  x[1] * v[0] + y[1] * v[1] + z[1] * v[2],
74  x[2] * v[0] + y[2] * v[1] + z[2] * v[2]);
75  }
76 };
77 
78 }
79 
80 //-----------------------------------------------------------------------------
81 
83  ACG::Vec3d _pOnPlane, ACG::Vec3d _n, ACG::Vec3d* _pOut) {
84  OpenMeshTriangleBSPT<TriMesh>* bsp = _triMeshObject->requestTriangleBsp();
86  rayInt = bsp->raycollision(_pOnPlane, _n);
87 
88  if (rayInt.empty())
89  return false;
90  int i = -1;
91  double smDist = 10e10;
92 
93  for (unsigned int j = 0; j < rayInt.size(); j++) {
94  ACG::Vec3d p = _pOnPlane + _n * rayInt[j].second, dir = _center - p;
95  const double dist = dir.norm();
96  if (dist < smDist) {
97  smDist = dist;
98  if (_pOut)
99  *_pOut = p; //+ norAtInt * 0.002;//that would fix lines below the surface, but what is the correct scale?
100  i = j;
101  }
102  }
103 
104  return i != -1;
105 }
106 
107 //-----------------------------------------------------------------------------
108 
110  double* r, ACG::Vec3d* _onPlaneO) {
111  ACG::Vec3d n = _circleData->circleNormal_, x0 = _circleData->circleCenter_;
112  double t = ((n | x0) - (n | _hit_Point)) / n.sqrnorm();
113  ACG::Vec3d onPlane = _hit_Point + t * n, d = onPlane - x0;
114  if (r)
115  *r = d.norm();
116  if (_onPlaneO)
117  *_onPlaneO = onPlane;
118  TriMeshObject* mesh;
119  if (PluginFunctions::getObject(_circleData->circleMeshIndex_, mesh))
120  return createCircle_getPointOnMesh(mesh, x0, onPlane, n, _pOut);
121  else
122  return false;
123 }
124 
125 //-----------------------------------------------------------------------------
126 
128  ACG::Vec3d pOnMesh, pOnPlane;
129  double r;
130  if (!createCircle_getHitInfo(_circleData, _hit_point, &pOnMesh, &r, &pOnPlane))
131  return pOnPlane; //no point on the mesh was found...
132  else
133  return pOnMesh;
134 }
135 
136 //-----------------------------------------------------------------------------
137 
138 void PolyLinePlugin::updatePolyEllipse(PolyLineObject* _lineObject, unsigned int _pointCount) {
139  PolyLineCircleData* lineData = dynamic_cast<PolyLineCircleData*>(_lineObject->objectData(CIRCLE_DATA));
140 
141  TriMeshObject* mesh;
142  if(!PluginFunctions::getObject(lineData->circleMeshIndex_, mesh))
143  return;//if there is no mesh available do not try to recreate the circle
144 
145  const double theta = 2.0 * M_PI / double(_pointCount);
146  // _pointCount += tool_->rb_CloseCircle->isChecked() ? 0 : -1;
147  const double r2 = lineData->circleMainRadius_, r1 = lineData->circleSideRadius_;
148  const Onb basis(lineData);
149 
150  _lineObject->line()->clear();
151  _lineObject->line()->set_closed(tool_->rb_CloseCircle->isChecked());
152 
153  for (unsigned int i = 0; i <= _pointCount; i++) {
154  const double tanTheta_i = tan(theta * i);
155  double x = (r1 * r2) / sqrt(r2 * r2 + r1 * r1 * tanTheta_i * tanTheta_i);
156  x = ((theta * i) <= M_PI_2 || (theta * i) > (3.0 * M_PI_2)) ? x : -x;
157  const double y = tanTheta_i * x;
158  ACG::Vec3d pOnMesh;
159  const ACG::Vec3d pOnPlane(y, 0, x), //this is in the local coord system!
160  pInWorld = basis.toWorld(pOnPlane) + lineData->circleCenter_;
161  if(moveCircle_IsFloating)
162  _lineObject->line()->add_point(pInWorld);
163  else if(createCircle_getHitInfo(lineData, pInWorld, &pOnMesh))
164  _lineObject->line()->add_point(pOnMesh);
165  }
166 
167  emit updatedObject(_lineObject->id(), UPDATE_GEOMETRY | UPDATE_TOPOLOGY);
168 }
169 
170 //-----------------------------------------------------------------------------
171 
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:73
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
bool getObject(int _identifier, BSplineCurveObject *&_object)
std::vector< std::pair< Handle, Scalar > > RayCollision
Store nearest neighbor information.
Definition: BSPImplT.hh:105
void set_closed(const bool _c)
Set if the polyline should be closed and therefore forms a loop.
Definition: PolyLineT.hh:119
int id() const
Definition: BaseObject.cc:201
PolyLine * line()
return a pointer to the line
void clear()
Clear the current polyline.
Definition: PolyLineT.cc:187
void updatePolyEllipse(PolyLineObject *_lineObject, unsigned int _pointCount)
Generates points for the ellipse.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
OMTriangleBSP * requestTriangleBsp()
Definition: MeshObjectT.cc:756
ACG::Vec3d createCircle_getHit(PolyLineCircleData *_circleData, ACG::Vec3d _hit_point)
Returns point on mesh or point on the normal plane.
bool createCircle_getHitInfo(PolyLineCircleData *_circleData, ACG::Vec3d _hit_Point, ACG::Vec3d *_pOut=0, double *_r=0, ACG::Vec3d *_onPlane=0)
Calculates common info.
void add_point(const Point &_p)
Append a point to the polyline.
Definition: PolyLineT.cc:288
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
Definition: Vector11T.hh:408
decltype(std::declval< S >()*std::declval< S >()) sqrnorm() const
compute squared euclidean norm
Definition: Vector11T.hh:396
RayCollision raycollision(const Point &_p, const Point &_r) const
intersect mesh with ray
bool createCircle_getPointOnMesh(TriMeshObject *_triMeshObject, ACG::Vec3d _center, ACG::Vec3d _pOnPlane, ACG::Vec3d _n, ACG::Vec3d *_pOut)
Calculates a point on the mesh.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
PerObjectData * objectData(QString _dataName)
Returns the object data pointer.
Definition: BaseObject.cc:814