1 // This library is distributed in the hope that it will be useful,
2 // but WITHOUT ANY WARRANTY; without even the implied warranty of
3 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4 // Lesser General Public License for more details.
6 // You should have received a copy of the GNU Lesser General Public
7 // License along with this library; if not, write to the Free Software
8 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
12 #include "VTKViewer_ConvexTool.h"
14 #include <vtkUnstructuredGrid.h>
15 #include <vtkTriangle.h>
16 #include <vtkConvexPointSet.h>
24 static float FACE_ANGLE_TOLERANCE=1.5;
26 typedef std::set<vtkIdType> TUIDS; // unique ids
27 typedef std::map<vtkIdType,TUIDS> TPTOIDS; // id points -> unique ids
32 static int MYDEBUG = 0;
34 static int MYDEBUG = 0;
37 static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center)
40 center[0] = center[1] = center[2] = 0.0;
42 int numIds=theptIds.size();
44 // get the center of the cell
45 for (int i=0; i < numIds; i++)
47 p = theGrid->GetPoint(theptIds[i]);
48 for (int j=0; j < 3; j++)
53 for (int j=0; j<3; j++)
59 static void ReverseIds(TCell &theIds)
63 vtkIdType npts=theIds.size();
65 for(i=0;i<(npts/2);i++){
67 theIds[i] = theIds[npts-i-1];
68 theIds[npts-i-1] = tmp;
72 // caclulation of connected faces (faceId -> (faceId1,faceId2, ...))
73 void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output)
75 TCellArray::const_iterator f2pIter = f2points.begin();
77 for( ; f2pIter!=f2points.end() ; f2pIter++ ){
78 vtkIdType faceId = f2pIter->first;
79 TCell face_points = f2pIter->second;
80 int nb_face_points = face_points.size();
84 TPTOIDS::const_iterator faces1;
85 TPTOIDS::const_iterator faces2;
88 faces1 = p2faces.find(id1);
92 for(int i=1 ; i<nb_face_points ; i++ ){
96 faces2 = p2faces.find(id2);
98 std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(),
99 std::inserter(output_faces,output_faces.begin()));
104 id1 = face_points[0];
105 faces1 = p2faces.find(id1);
106 std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(),
107 std::inserter(output_faces,output_faces.begin()));
109 output_faces.erase(faceId); // erase the face id for which we found friends
112 cout << "fId[" << faceId <<"]: ";
113 std::copy(output_faces.begin(), output_faces.end(), std::ostream_iterator<vtkIdType>(cout, " "));
117 face2face_output[faceId] = output_faces;
121 bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid,
122 vtkIdType theFId1, vtkIdType theFId2,
123 TUIDS FpIds1, TUIDS FpIds2 )
127 std::set_intersection(FpIds1.begin(), FpIds1.end(), FpIds2.begin(), FpIds2.end(),
128 std::inserter(common_ids,common_ids.begin()));
130 /* Number of common ids = 2 (A1,A2)
133 _ _ _ _ _ _ _ _ _ vectors:
142 |_ _ _ _ _/ \_ _ _ _ _|
146 TUIDS::iterator common_iter = common_ids.begin();
147 if(common_ids.size() == 2){
148 TUIDS::iterator loc_id1_0 = FpIds1.find(*(common_iter));
150 TUIDS::iterator loc_id1_1 = FpIds1.find(*(common_iter));
152 TUIDS::iterator loc_id2_0 = FpIds1.begin();
153 TUIDS::iterator loc_id2_1 = FpIds2.begin();
155 vtkIdType A1 = *loc_id1_0;
156 vtkIdType A2 = *loc_id1_1;
160 for(;loc_id2_0!=FpIds1.end();loc_id2_0++)
161 if(*loc_id2_0 != A1 && *loc_id2_0!= A2){
165 for(;loc_id2_1!=FpIds2.end();loc_id2_1++)
166 if(*loc_id2_1 != A1 && *loc_id2_1!= A2){
170 if(MYDEBUG) cout <<endl;
171 if(MYDEBUG) cout << "FId_1="<<theFId1<<" FId_2="<<theFId2<<endl;
172 if(MYDEBUG) cout << " A1="<<A1<<" A2="<<A2<<" B1="<<B1<<" C1="<<C1<<" ->";
174 float v1[3],v2[3],v3[3];
175 p[0] = theGrid->GetPoint(A1);
176 p[1] = theGrid->GetPoint(A2);
177 p[2] = theGrid->GetPoint(B1);
178 p[3] = theGrid->GetPoint(C1);
180 for(int i=0;i<3;i++){
181 v1[i] = p[1][i] - p[0][i];
182 v2[i] = p[2][i] - p[0][i];
183 v3[i] = p[3][i] - p[0][i];
188 vtkMath::Cross(v2,v1,vec_b1);
190 vtkMath::Cross(v1,v3,vec_b2);
192 float b1 = vtkMath::Norm(vec_b1);
194 float b2 = vtkMath::Norm(vec_b2);
196 float angle=180*acosf(vtkMath::Dot(vec_b1,vec_b2)/(b1*b2))/vtkMath::Pi();
198 if( angle <= FACE_ANGLE_TOLERANCE )
201 for(int k=0;k<4;k++){
203 for(int j=0;j<2;j++){
204 cout << p[k][j] << ",";
206 cout << p[k][2] << ") ";
208 cout << "angle="<<angle<<endl;
211 } else if (common_ids.size() >2){
212 // not implemented yet
213 if(MYDEBUG) cout << "Warning! VTKViewer_ConvexTool::IsConnectedFacesOnOnePlane()";
215 // one or no connection ... continue
221 void GetAllFacesOnOnePlane( TPTOIDS theFaces, vtkIdType faceId,
222 TUIDS &new_faces, TCell &new_faces_v2 )
224 if (new_faces.find(faceId) != new_faces.end()) return;
226 new_faces.insert(new_faces.begin(),faceId);
227 new_faces_v2.push_back(faceId);
229 TPTOIDS::const_iterator aIter1 = theFaces.find(faceId);
230 if(aIter1!=theFaces.end()){
231 TUIDS::const_iterator aIter2 = (aIter1->second).begin();
232 for(;aIter2!=(aIter1->second).end();aIter2++){
233 if (new_faces.find(*aIter2) != new_faces.end()) continue;
234 GetAllFacesOnOnePlane(theFaces,*aIter2,
235 new_faces,new_faces_v2); // recurvise
241 void GetSumm(TCell v1,TCell v2,TCell &output)
245 if(MYDEBUG) cout << "========================================="<<endl;
246 if(MYDEBUG) cout << "v1:";
247 if(MYDEBUG) std::copy(v1.begin(), v1.end(), std::ostream_iterator<vtkIdType>(cout, " "));
248 if(MYDEBUG) cout << "\tv2:";
249 if(MYDEBUG) std::copy(v2.begin(), v2.end(), std::ostream_iterator<vtkIdType>(cout, " "));
250 if(MYDEBUG) cout << endl;
253 std::copy(v1.begin(), v1.end(), std::inserter(v1_set,v1_set.begin()));
255 std::copy(v2.begin(), v2.end(), std::inserter(v2_set,v2_set.begin()));
256 TUIDS tmpIntersection;
257 std::set_intersection(v1_set.begin(),v1_set.end(),v2_set.begin(),v2_set.end(), std::inserter(tmpIntersection,tmpIntersection.begin()));
258 if(MYDEBUG) std::copy(tmpIntersection.begin(),tmpIntersection.end(), std::ostream_iterator<vtkIdType>(cout, " "));
259 if(MYDEBUG) cout << endl;
261 if(tmpIntersection.size() < 2)
262 if(MYDEBUG) cout << __FILE__ << "[" << __LINE__ << "]: Warning ! Wrong ids" << endl;
264 TCell::iterator v1_iter = v1.begin();
266 for(;v1_iter!=v1.end();v1_iter++){
268 vtkIdType curr_id = *v1_iter;
270 output.push_back(curr_id);
272 if(tmpIntersection.find(curr_id) != tmpIntersection.end()){
273 TCell::iterator v1_iter_tmp;
274 v1_iter_tmp = v1_iter;
277 if(v1_iter==v1.end()) v1_iter=v1.begin();
281 if(tmpIntersection.find(curr_id) != tmpIntersection.end()){
282 TCell::iterator v2_iter = v2.begin();
283 for(;v2_iter!=v2.end();v2_iter++){
284 vtkIdType v2_id = *v2_iter;
285 if(tmpIntersection.find(v2_id) == tmpIntersection.end())
286 output.push_back(v2_id);
290 v1_iter = v1_iter_tmp;
296 if(MYDEBUG) cout << "Result: " ;
297 if(MYDEBUG) std::copy(output.begin(),output.end(),std::ostream_iterator<vtkIdType>(cout, " "));
298 if(MYDEBUG) cout << endl;
301 void GetPolygonalFaces(vtkUnstructuredGrid* theGrid,int cellId,TCellArray &outputCellArray)
303 if (theGrid->GetCellType(cellId) == VTK_CONVEX_POINT_SET){
304 // get vtkCell type = VTK_CONVEX_POINT_SET
305 if(vtkConvexPointSet* convex = static_cast<vtkConvexPointSet*>(theGrid->GetCell(cellId))){
307 float convex_center[3]; // convex center point coorinat
308 int aNbFaces = convex->GetNumberOfFaces();
309 int numPts = convex->GetNumberOfPoints();
311 TPTOIDS p2faces; // key=pointId , value facesIds set
313 for(int i=0;i<numPts;i++)
314 convex_ids.push_back(convex->GetPointId(i));
316 GetCenter(theGrid,convex_ids,convex_center);
318 for (vtkIdType faceId=0; faceId < aNbFaces; faceId++){
319 vtkCell *aFace = convex->GetFace(faceId);
320 int numFacePts = aFace->GetNumberOfPoints();
324 for(i=0;i<numFacePts;i++)
325 aIds.push_back(aFace->GetPointId(i));
327 float v_a[3],v_b[3],v_convex2face[3]; // vectors
328 float *id_0,*id_1,*id_n;
329 /*=============================================
331 _ / id_n | v_b {id_0,id_n}
343 ============================================*/
344 id_0 = theGrid->GetPoint(aIds[0]);
345 id_1 = theGrid->GetPoint(aIds[1]);
346 id_n = theGrid->GetPoint(aIds[numFacePts-1]);
349 v_a[i] = id_1[i] - id_0[i];
350 v_b[i] = id_n[i] - id_0[i];
351 v_convex2face[i] = id_0[i] - convex_center[i];
354 if (vtkMath::Determinant3x3(v_a,v_b,v_convex2face) < 0){
358 for(i=0;i<(int)aIds.size();i++){
359 TUIDS &acell = p2faces[aIds[i]];
360 acell.insert(faceId);
363 f2points[faceId] = aIds;
368 GetFriends(p2faces,f2points,face2face);
372 // copy TCellArray::f2points to TPTOIDS::face2points
373 for(TCellArray::iterator f2points_iter=f2points.begin();
374 f2points_iter!=f2points.end();
378 for(TCell::iterator points_iter=(f2points_iter->second).begin();
379 points_iter!=(f2points_iter->second).end();
381 tmp.insert(*points_iter);
383 face2points[f2points_iter->first] = tmp;
387 TPTOIDS new_face2faces; // which connected and in one plane
389 TPTOIDS::const_iterator aF2FIter = face2face.begin();
390 for(;aF2FIter!=face2face.end();aF2FIter++){
391 vtkIdType f_key = aF2FIter->first;
392 TUIDS &faces = new_face2faces[f_key];
393 //faces.insert(f_key);
394 TUIDS f_friends = aF2FIter->second;
395 TUIDS::const_iterator a_friends_iter = f_friends.begin();
396 for(;a_friends_iter!=f_friends.end();a_friends_iter++){
397 vtkIdType friend_id = *a_friends_iter;
398 if( IsConnectedFacesOnOnePlane(theGrid,f_key,friend_id,
399 (face2points.find(f_key))->second,
400 (face2points.find(friend_id))->second)){
401 faces.insert(friend_id);
404 } // end a_friends_iter
409 TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin();
410 cout << "Connected faces and on plane:" << endl;
411 for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){
412 cout << "Group ["<<new_face2face_iter->first<<"] :";
413 TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
414 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
415 cout << " " << *new_faces_iter ;
420 TPTOIDS output_newid2face;
421 TCellArray output_newid2face_v2;
424 TUIDS already_in_tmp;
426 TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin();
427 for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){
428 if(already_in.find(new_face2face_iter->first) != already_in.end())
430 if(new_face2face_iter->second.size() > 1)
433 TCell &tmp_v2 = output_newid2face_v2[k];
434 tmp_v2.push_back(new_face2face_iter->first);
435 already_in.insert(new_face2face_iter->first);
437 TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
438 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
439 if(already_in.find(*new_faces_iter) != already_in.end()) continue;
440 already_in.insert(*new_faces_iter);
442 already_in_tmp.clear();
443 already_in_tmp.insert(new_face2face_iter->first);
445 TUIDS &tmp = output_newid2face[k];
446 GetAllFacesOnOnePlane(new_face2faces,*new_faces_iter,
447 already_in_tmp,tmp_v2);
449 for(TUIDS::const_iterator aIter=already_in_tmp.begin();
450 aIter!=already_in_tmp.end();
453 already_in.insert(*aIter);
462 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
464 TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin();
465 for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){
466 cout << "Group ["<<new_face2face_iter->first<<"] :";
467 TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
468 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
469 cout << " " << *new_faces_iter ;
473 cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
474 cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
475 cout << "+++++++++++++++++++++++ ++ ++ ++++++++++++++++++++++++++++"<<endl;
476 cout << "+++++++++++++++++++++++++ ++++++++++++++++++++++++++++++"<<endl;
477 cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
479 TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin();
480 for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){
481 cout << "Group ["<<new_face2face_iter->first<<"] :";
482 TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
483 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
484 cout << " " << *new_faces_iter ;
489 TCellArray output_new_face2ids;
491 // TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin();
492 // for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){
494 // vtkIdType new_faceId = new_face2face_iter->first;
495 // TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
496 // vtkIdType fId0 = *new_faces_iter;
497 // TCellArray::const_iterator pIds0_iter = f2points.find(fId0);
498 // TCell pIds0 = pIds0_iter->second;
499 // TCell &output = output_new_face2ids[new_faceId];
501 // if(new_face2face_iter->second.size() > 2 ){}
502 // for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
504 // vtkIdType faceId = *new_faces_iter;
505 // // find how much nodes in face (f2points)
506 // TCellArray::const_iterator pIds_iter = f2points.find(faceId);
507 // TCell pIds = pIds_iter->second;
509 // GetSumm(pIds0,pIds,output);
512 // } // end new_faces_iter
514 // } // new_face2face_iter
518 TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin();
519 for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){
521 vtkIdType new_faceId = new_face2face_iter->first;
522 TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
523 vtkIdType fId0 = *new_faces_iter;
524 TCellArray::const_iterator pIds0_iter = f2points.find(fId0);
525 TCell pIds0 = pIds0_iter->second;
526 TCell &output = output_new_face2ids[new_faceId];
528 if(new_face2face_iter->second.size() == 1 ){
529 TCellArray::const_iterator pIds_iter = f2points.find(fId0);
530 TCell pIds = pIds_iter->second;
534 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
536 vtkIdType faceId = *new_faces_iter;
537 // find how much nodes in face (f2points)
538 TCellArray::const_iterator pIds_iter = f2points.find(faceId);
539 TCell pIds = pIds_iter->second;
541 GetSumm(pIds0,pIds,output);
544 } // end new_faces_iter
546 } // new_face2face_iter
550 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
551 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
552 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
554 outputCellArray = output_new_face2ids;//f2points;