Developer Documentation
Loading...
Searching...
No Matches
PlanePluginT_impl.hh
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2020, 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#define PLANEPLUGIN_CC
43
44#include "PlanePlugin.hh"
45#include <iostream>
46
48
49#include <ACG/Scenegraph/LineNode.hh>
50
51#include <ACG/Geometry/Algorithms.hh>
52#include <ACG/Scenegraph/DrawModes.hh>
53
54
55//------------------------------------------------------------------------------
56
66template< class MeshT >
67std::vector< ACG::Vec3d > PlanePlugin::getIntersectionPoints( MeshT* _mesh ,
68 uint _fh ,
69 ACG::Vec3d _planeNormal ,
70 ACG::Vec3d _planePoint ,
71 bool& _closed )
72{
74 _mesh->add_property(cut,"Plane Cut Property" );
75
76 typename MeshT::FaceHandle fh ( _fh );
77
78 typename MeshT::FaceHandle current_face = typename MeshT::FaceHandle(_fh);
79
80 for(auto he_it : _mesh->halfedges())
81 _mesh->property( cut, he_it ) = false;
82// int id = -1;
83
84 bool stop = false;
85 bool nothingFound = true;
86 int expansionLevel = 0;
87 bool flip_dir = false;
88 _closed = true;
89
90 std::vector< ACG::Vec3d > linePoints;
91
92 std::vector< typename MeshT::FaceHandle > startCandidates;
93 std::vector< typename MeshT::FaceHandle > expandable;
94 expandable.push_back( fh );
95
96 while (!stop) {
97 stop = true;
98
99 // First check the face we are in
100 for ( typename MeshT::FaceHalfedgeIter fhe_it( *_mesh, current_face ); fhe_it.is_valid(); ++fhe_it){
101 if ( _mesh->property(cut,*fhe_it) )
102 continue;
103
104 typename MeshT::Point p0 = _mesh->point( _mesh->from_vertex_handle(*fhe_it) );
105 typename MeshT::Point p1 = _mesh->point( _mesh->to_vertex_handle(*fhe_it) );
106
107 typename MeshT::Point u = p1 - p0;
108 typename MeshT::Point w = p0 - _planePoint;
109
110 double D = (_planeNormal | u);
111 double N = - (_planeNormal | w);
112
113 // compute intersect param
114 double sI = N / D;
115 if (sI < 0.0 || sI > 1.0 ) // intersection on ray, but not within line segment
116 continue;
117
118 nothingFound = false;
119
120 stop = false;
121 _mesh->property(cut,*fhe_it) = true;
122 _mesh->property(cut,_mesh->opposite_halfedge_handle(*fhe_it)) = true;
123 current_face = _mesh->face_handle(_mesh->opposite_halfedge_handle(*fhe_it));
124
125 if (!current_face.is_valid())
126 stop = true;
127
128 typename MeshT::Point cutPoint = p0 + sI * u;
129
130 // add new point
131 if ( !flip_dir )
132 linePoints.push_back(cutPoint);
133 else {
134 linePoints.insert( linePoints.begin() , cutPoint );
135 _closed = false;
136 }
137
138 break;
139 }
140
141 if ( stop ){
142 if ( nothingFound ){
143 if ( startCandidates.empty() ){
144
145 if (expansionLevel > 3 )
146 std::cerr << "Expanded" << expansionLevel << "rings but still nothing found!" << std::endl;
147 else{
148
149 //add the "expansionLevel"-ring of the start-face to the start candidates
150 for (uint i=0; i < expandable.size(); i++)
151 for( typename MeshT::FaceFaceIter ff_it(*_mesh, expandable[i]); ff_it.is_valid(); ++ff_it )
152 startCandidates.push_back( *ff_it );
153
154 expandable.clear();
155 expansionLevel++;
156 }
157 }
158
159 if ( !startCandidates.empty() ){
160 fh = startCandidates.back();
161 expandable.push_back( fh );
162 startCandidates.pop_back();
163 stop = false;
164 }
165
166 }else if (! flip_dir ){
167 flip_dir = true;
168 stop = false;
169 }
170
171 current_face = fh;
172 }
173 }
174
175 _mesh->remove_property( cut );
176
177 return linePoints;
178}
179
180//------------------------------------------------------------------------------
181
189template< class MeshT >
190typename MeshT::EdgeHandle
191PlanePlugin::getCuttedEdge(MeshT& _mesh, ACG::Vec3d& _planeNormal, ACG::Vec3d& _planePoint){
192
193 typename MeshT::Scalar minDistance = FLT_MAX;
194 typename MeshT::EdgeHandle minEdge(-1);
195
196 for (auto e_it : _mesh.edges()){
197
198 typename OpenMesh::SmartHalfedgeHandle hh = e_it.h0();
199
200 //get intersection point with plane
201 typename MeshT::Point p0 = _mesh.point( hh.from() );
202 typename MeshT::Point p1 = _mesh.point( hh.to() );
203
204 typename MeshT::Point u = p1 - p0;
205 typename MeshT::Point w = p0 - _planePoint;
206
207 double D = (_planeNormal | u);
208 double N = - (_planeNormal | w);
209
210 // compute intersect param
211 double sI = N / D;
212
213 if (sI >= 0.0 && sI <= 1.0 ){
214
215 typename MeshT::Point cutPoint = p0 + sI * u;
216
217 typename MeshT::Scalar dist = (cutPoint - _planePoint).sqrnorm();
218
219 if ( dist < minDistance ){
220
221 minDistance = dist;
222 minEdge = e_it;
223 }
224 }
225 }
226
227 return minEdge;
228}
VertexHandle from_vertex_handle(HalfEdgeHandle _h) const
Get the vertex the halfedge starts from.
VertexHandle to_vertex_handle(HalfEdgeHandle _h) const
Get the vertex the halfedge points to.
std::vector< ACG::Vec3d > getIntersectionPoints(MeshT *_mesh, uint _fh, ACG::Vec3d _planeNormal, ACG::Vec3d _planePoint, bool &_closed)
get the points from the intersection between mesh and plane
MeshT::EdgeHandle getCuttedEdge(MeshT &_mesh, ACG::Vec3d &_planeNormal, ACG::Vec3d &_planePoint)
get an edge of the mesh that is cut by the plane
SmartVertexHandle from() const
Returns vertex at start of halfedge.
SmartVertexHandle to() const
Returns vertex pointed to by halfedge.