Developer Documentation
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 
66 template< class MeshT >
67 std::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  typename MeshT::HalfedgeIter e_it, e_end = _mesh->halfedges_end();
81  for( e_it = _mesh->halfedges_begin(); e_it != e_end; ++e_it )
82  _mesh->property( cut, *e_it ) = false;
83 // int id = -1;
84 
85  bool stop = false;
86  bool nothingFound = true;
87  int expansionLevel = 0;
88  bool flip_dir = false;
89  _closed = true;
90 
91  std::vector< ACG::Vec3d > linePoints;
92 
93  std::vector< typename MeshT::FaceHandle > startCandidates;
94  std::vector< typename MeshT::FaceHandle > expandable;
95  expandable.push_back( fh );
96 
97  while (!stop) {
98  stop = true;
99 
100  // First check the face we are in
101  for ( typename MeshT::FaceHalfedgeIter fhe_it( *_mesh, current_face ); fhe_it.is_valid(); ++fhe_it){
102  if ( _mesh->property(cut,*fhe_it) )
103  continue;
104 
105  typename MeshT::Point p0 = _mesh->point( _mesh->from_vertex_handle(*fhe_it) );
106  typename MeshT::Point p1 = _mesh->point( _mesh->to_vertex_handle(*fhe_it) );
107 
108  typename MeshT::Point u = p1 - p0;
109  typename MeshT::Point w = p0 - _planePoint;
110 
111  double D = (_planeNormal | u);
112  double N = - (_planeNormal | w);
113 
114  // compute intersect param
115  double sI = N / D;
116  if (sI < 0.0 || sI > 1.0 ) // intersection on ray, but not within line segment
117  continue;
118 
119  nothingFound = false;
120 
121  stop = false;
122  _mesh->property(cut,*fhe_it) = true;
123  _mesh->property(cut,_mesh->opposite_halfedge_handle(*fhe_it)) = true;
124  current_face = _mesh->face_handle(_mesh->opposite_halfedge_handle(*fhe_it));
125 
126  if (!current_face.is_valid())
127  stop = true;
128 
129  typename MeshT::Point cutPoint = p0 + sI * u;
130 
131  // add new point
132  if ( !flip_dir )
133  linePoints.push_back(cutPoint);
134  else {
135  linePoints.insert( linePoints.begin() , cutPoint );
136  _closed = false;
137  }
138 
139  break;
140  }
141 
142  if ( stop ){
143  if ( nothingFound ){
144  if ( startCandidates.empty() ){
145 
146  if (expansionLevel > 3 )
147  std::cerr << "Expanded" << expansionLevel << "rings but still nothing found!" << std::endl;
148  else{
149 
150  //add the "expansionLevel"-ring of the start-face to the start candidates
151  for (uint i=0; i < expandable.size(); i++)
152  for( typename MeshT::FaceFaceIter ff_it(*_mesh, expandable[i]); ff_it.is_valid(); ++ff_it )
153  startCandidates.push_back( *ff_it );
154 
155  expandable.clear();
156  expansionLevel++;
157  }
158  }
159 
160  if ( !startCandidates.empty() ){
161  fh = startCandidates.back();
162  expandable.push_back( fh );
163  startCandidates.pop_back();
164  stop = false;
165  }
166 
167  }else if (! flip_dir ){
168  flip_dir = true;
169  stop = false;
170  }
171 
172  current_face = fh;
173  }
174  }
175 
176  _mesh->remove_property( cut );
177 
178  return linePoints;
179 }
180 
181 //------------------------------------------------------------------------------
182 
190 template< class MeshT >
191 typename MeshT::EdgeHandle
192 PlanePlugin::getCuttedEdge(MeshT& _mesh, ACG::Vec3d& _planeNormal, ACG::Vec3d& _planePoint){
193 
194  typename MeshT::EdgeIter e_it;
195  typename MeshT::EdgeIter e_end = _mesh.edges_end();
196 
197  typename MeshT::Scalar minDistance = FLT_MAX;
198  typename MeshT::EdgeHandle minEdge(-1);
199 
200  for (e_it = _mesh.edges_begin(); e_it != e_end; ++e_it){
201 
202  typename MeshT::HalfedgeHandle hh = _mesh.halfedge_handle(*e_it, 0);
203 
204  //get intersection point with plane
205  typename MeshT::Point p0 = _mesh.point( _mesh.from_vertex_handle(hh) );
206  typename MeshT::Point p1 = _mesh.point( _mesh.to_vertex_handle(hh) );
207 
208  typename MeshT::Point u = p1 - p0;
209  typename MeshT::Point w = p0 - _planePoint;
210 
211  double D = (_planeNormal | u);
212  double N = - (_planeNormal | w);
213 
214  // compute intersect param
215  double sI = N / D;
216 
217  if (sI >= 0.0 && sI <= 1.0 ){
218 
219  typename MeshT::Point cutPoint = p0 + sI * u;
220 
221  typename MeshT::Scalar dist = (cutPoint - _planePoint).sqrnorm();
222 
223  if ( dist < minDistance ){
224 
225  minDistance = dist;
226  minEdge = *e_it;
227  }
228  }
229  }
230 
231  return minEdge;
232 }
MeshT::EdgeHandle getCuttedEdge(MeshT &_mesh, ACG::Vec3d &_planeNormal, ACG::Vec3d &_planePoint)
get an edge of the mesh that is cut by the plane
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