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
14 // File : VTKViewer_ConvexTool.cxx
15 // Author : Eugeny Nikolaev
19 #include "VTKViewer_ConvexTool.h"
21 #include <vtkUnstructuredGrid.h>
22 #include <vtkTriangle.h>
23 #include <vtkConvexPointSet.h>
30 static float FACE_TOLERANCE=0;
32 typedef std::set<vtkIdType> TUIDS; // unique ids
33 typedef std::map<vtkIdType,TUIDS> TPTOIDS; // id points -> unique ids
36 namespace CONVEX_TOOL{
38 static int MYDEBUG = 0;
40 static int MYDEBUG = 0;
43 static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center)
46 center[0] = center[1] = center[2] = 0.0;
48 int numIds=theptIds.size();
50 // get the center of the cell
51 for (int i=0; i < numIds; i++)
53 p = theGrid->GetPoint(theptIds[i]);
54 for (int j=0; j < 3; j++)
59 for (int j=0; j<3; j++)
65 static void ReverseIds(TCell &theIds){
68 vtkIdType npts=theIds.size();
70 for(i=0;i<(npts/2);i++){
72 theIds[i] = theIds[npts-i-1];
73 theIds[npts-i-1] = tmp;
77 // caclulation of connected faces (faceId -> (faceId1,faceId2, ...))
78 void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output)
80 TCellArray::const_iterator f2pIter = f2points.begin();
82 for( ; f2pIter!=f2points.end() ; f2pIter++ ){
83 vtkIdType faceId = f2pIter->first;
84 TCell face_points = f2pIter->second;
85 int nb_face_points = face_points.size();
89 TPTOIDS::const_iterator faces1;
90 TPTOIDS::const_iterator faces2;
93 faces1 = p2faces.find(id1);
97 for(int i=1 ; i<nb_face_points ; i++ ){
101 faces2 = p2faces.find(id2);
103 std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(),
104 inserter(output_faces,output_faces.begin()));
109 id1 = face_points[0];
110 faces1 = p2faces.find(id1);
111 std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(),
112 inserter(output_faces,output_faces.begin()));
114 output_faces.erase(faceId); // erase the face id for which we found friends
117 cout << "fId[" << faceId <<"]: ";
118 copy(output_faces.begin(), output_faces.end(), ostream_iterator<vtkIdType>(cout, " "));
122 face2face_output[faceId] = output_faces;
126 bool IsConnectedFacesOnOnePlane(vtkUnstructuredGrid* theGrid,
127 vtkIdType theFId1,vtkIdType theFId2,
128 TUIDS FpIds1,TUIDS FpIds2)
132 std::set_intersection(FpIds1.begin(), FpIds1.end(), FpIds2.begin(), FpIds2.end(),
133 inserter(common_ids,common_ids.begin()));
135 /* Number of common ids = 2 (A1,A2)
138 _ _ _ _ _ _ _ _ _ vectors:
147 |_ _ _ _ _/ \_ _ _ _ _|
151 TUIDS::iterator common_iter = common_ids.begin();
152 if(common_ids.size() == 2){
153 TUIDS::iterator loc_id1_0 = FpIds1.find(*(common_iter));
155 TUIDS::iterator loc_id1_1 = FpIds1.find(*(common_iter));
157 TUIDS::iterator loc_id2_0 = FpIds1.begin();
158 TUIDS::iterator loc_id2_1 = FpIds2.begin();
160 vtkIdType A1 = *loc_id1_0;
161 vtkIdType A2 = *loc_id1_1;
165 for(;loc_id2_0!=FpIds1.end();loc_id2_0++)
166 if(*loc_id2_0 != A1 && *loc_id2_0!= A2){
170 for(;loc_id2_1!=FpIds2.end();loc_id2_1++)
171 if(*loc_id2_1 != A1 && *loc_id2_1!= A2){
175 if(MYDEBUG) cout <<endl;
176 if(MYDEBUG) cout << "FId_1="<<theFId1<<" FId_2="<<theFId2<<endl;
177 if(MYDEBUG) cout << " A1="<<A1<<" A2="<<A2<<" B1="<<B1<<" C1="<<C1<<" ->";
179 float v1[3],v2[3],v3[3];
180 p[0] = theGrid->GetPoint(A1);
181 p[1] = theGrid->GetPoint(A2);
182 p[2] = theGrid->GetPoint(B1);
183 p[3] = theGrid->GetPoint(C1);
185 for(int i=0;i<3;i++){
186 v1[i] = p[1][i] - p[0][i];
187 v2[i] = p[2][i] - p[0][i];
188 v3[i] = p[3][i] - p[0][i];
192 float det = vtkMath::Determinant3x3(v1,v2,v3);
193 // float det = v1[0]*(v2[1]*v3[2]-v2[2]*v3[1]) -
194 // v1[1]*(v2[0]*v3[2]-v2[2]*v3[0]) +
195 // v1[2]*(v2[0]*v3[1]-v2[1]*v3[0]);
199 if( det <= FACE_TOLERANCE )
202 for(int k=0;k<4;k++){
204 for(int j=0;j<2;j++){
205 cout << p[k][j] << ",";
207 cout << p[k][2] << ") ";
212 } else if (common_ids.size() >2){
213 // not implemented yet
214 if(MYDEBUG) cout << "Warning! VTKViewer_ConvexTool::IsConnectedFacesOnOnePlane()";
216 // one or no connection ... continue
222 void GetAllFacesOnOnePlane(TPTOIDS theFaces, vtkIdType faceId,
223 TUIDS &new_faces,TCell &new_faces_v2){
225 if (new_faces.find(faceId) != new_faces.end()) return;
227 new_faces.insert(new_faces.begin(),faceId);
228 new_faces_v2.push_back(faceId);
230 TPTOIDS::const_iterator aIter1 = theFaces.find(faceId);
231 if(aIter1!=theFaces.end()){
232 TUIDS::const_iterator aIter2 = (aIter1->second).begin();
233 for(;aIter2!=(aIter1->second).end();aIter2++){
234 if (new_faces.find(*aIter2) != new_faces.end()) continue;
235 GetAllFacesOnOnePlane(theFaces,*aIter2,
236 new_faces,new_faces_v2); // recurvise
242 void GetSumm(TCell v1,TCell v2,TCell &output){
246 if(MYDEBUG) cout << "========================================="<<endl;
247 if(MYDEBUG) cout << "v1:";
248 if(MYDEBUG) copy(v1.begin(), v1.end(), ostream_iterator<vtkIdType>(cout, " "));
249 if(MYDEBUG) cout << "\tv2:";
250 if(MYDEBUG) copy(v2.begin(), v2.end(), ostream_iterator<vtkIdType>(cout, " "));
251 if(MYDEBUG) cout << endl;
254 copy(v1.begin(), v1.end(), inserter(v1_set,v1_set.begin()));
256 copy(v2.begin(), v2.end(), inserter(v2_set,v2_set.begin()));
257 TUIDS tmpIntersection;
258 set_intersection(v1_set.begin(),v1_set.end(),v2_set.begin(),v2_set.end(),inserter(tmpIntersection,tmpIntersection.begin()));
259 if(MYDEBUG) copy(tmpIntersection.begin(),tmpIntersection.end(),ostream_iterator<vtkIdType>(cout, " "));
260 if(MYDEBUG) cout << endl;
262 if(tmpIntersection.size() < 2)
263 if(MYDEBUG) cout << __FILE__ << "[" << __LINE__ << "]: Warning ! Wrong ids" << endl;
265 TCell::iterator v1_iter = v1.begin();
267 for(;v1_iter!=v1.end();v1_iter++){
269 vtkIdType curr_id = *v1_iter;
271 output.push_back(curr_id);
273 if(tmpIntersection.find(curr_id) != tmpIntersection.end()){
274 TCell::iterator v1_iter_tmp;
275 v1_iter_tmp = v1_iter;
278 if(v1_iter==v1.end()) v1_iter=v1.begin();
282 if(tmpIntersection.find(curr_id) != tmpIntersection.end()){
283 TCell::iterator v2_iter = v2.begin();
284 for(;v2_iter!=v2.end();v2_iter++){
285 vtkIdType v2_id = *v2_iter;
286 if(tmpIntersection.find(v2_id) == tmpIntersection.end())
287 output.push_back(v2_id);
291 v1_iter = v1_iter_tmp;
297 if(MYDEBUG) cout << "Result: " ;
298 if(MYDEBUG) copy(output.begin(),output.end(),ostream_iterator<vtkIdType>(cout, " "));
299 if(MYDEBUG) cout << endl;
302 void GetPolygonalFaces(vtkUnstructuredGrid* theGrid,int cellId,TCellArray &outputCellArray)
304 if (theGrid->GetCellType(cellId) == VTK_CONVEX_POINT_SET){
305 // get vtkCell type = VTK_CONVEX_POINT_SET
306 if(vtkConvexPointSet* convex = static_cast<vtkConvexPointSet*>(theGrid->GetCell(cellId))){
308 float convex_center[3]; // convex center point coorinat
309 int aNbFaces = convex->GetNumberOfFaces();
310 int numPts = convex->GetNumberOfPoints();
312 TPTOIDS p2faces; // key=pointId , value facesIds set
314 for(int i=0;i<numPts;i++)
315 convex_ids.push_back(convex->GetPointId(i));
317 GetCenter(theGrid,convex_ids,convex_center);
319 for (vtkIdType faceId=0; faceId < aNbFaces; faceId++){
320 vtkCell *aFace = convex->GetFace(faceId);
321 int numFacePts = aFace->GetNumberOfPoints();
324 for(int 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]);
348 for(int i=0;i<3;i++){
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(int i=0;i<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
390 TPTOIDS::const_iterator aF2FIter = face2face.begin();
391 for(;aF2FIter!=face2face.end();aF2FIter++){
392 vtkIdType f_key = aF2FIter->first;
393 TUIDS &faces = new_face2faces[f_key];
394 //faces.insert(f_key);
395 TUIDS f_friends = aF2FIter->second;
396 TUIDS::const_iterator a_friends_iter = f_friends.begin();
397 for(;a_friends_iter!=f_friends.end();a_friends_iter++){
398 vtkIdType friend_id = *a_friends_iter;
399 if( IsConnectedFacesOnOnePlane(theGrid,f_key,friend_id,
400 (face2points.find(f_key))->second,
401 (face2points.find(friend_id))->second)){
402 faces.insert(friend_id);
405 } // end a_friends_iter
410 TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin();
411 cout << "Connected faces and on plane:" << endl;
412 for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){
413 cout << "Group ["<<new_face2face_iter->first<<"] :";
414 TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
415 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
416 cout << " " << *new_faces_iter ;
421 TPTOIDS output_newid2face;
422 TCellArray output_newid2face_v2;
425 TUIDS already_in_tmp;
427 TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin();
428 for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){
429 if(already_in.find(new_face2face_iter->first) != already_in.end())
431 if(new_face2face_iter->second.size() > 1)
434 TCell &tmp_v2 = output_newid2face_v2[k];
435 tmp_v2.push_back(new_face2face_iter->first);
436 already_in.insert(new_face2face_iter->first);
438 TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
439 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
440 if(already_in.find(*new_faces_iter) != already_in.end()) continue;
441 already_in.insert(*new_faces_iter);
443 already_in_tmp.clear();
444 already_in_tmp.insert(new_face2face_iter->first);
446 TUIDS &tmp = output_newid2face[k];
447 GetAllFacesOnOnePlane(new_face2faces,*new_faces_iter,
448 already_in_tmp,tmp_v2);
450 for(TUIDS::const_iterator aIter=already_in_tmp.begin();
451 aIter!=already_in_tmp.end();
454 already_in.insert(*aIter);
463 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
465 TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin();
466 for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){
467 cout << "Group ["<<new_face2face_iter->first<<"] :";
468 TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
469 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
470 cout << " " << *new_faces_iter ;
474 cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
475 cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
476 cout << "+++++++++++++++++++++++ ++ ++ ++++++++++++++++++++++++++++"<<endl;
477 cout << "+++++++++++++++++++++++++ ++++++++++++++++++++++++++++++"<<endl;
478 cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
480 TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin();
481 for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){
482 cout << "Group ["<<new_face2face_iter->first<<"] :";
483 TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
484 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
485 cout << " " << *new_faces_iter ;
490 TCellArray output_new_face2ids;
492 // TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin();
493 // for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){
495 // vtkIdType new_faceId = new_face2face_iter->first;
496 // TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
497 // vtkIdType fId0 = *new_faces_iter;
498 // TCellArray::const_iterator pIds0_iter = f2points.find(fId0);
499 // TCell pIds0 = pIds0_iter->second;
500 // TCell &output = output_new_face2ids[new_faceId];
502 // if(new_face2face_iter->second.size() > 2 ){}
503 // for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
505 // vtkIdType faceId = *new_faces_iter;
506 // // find how much nodes in face (f2points)
507 // TCellArray::const_iterator pIds_iter = f2points.find(faceId);
508 // TCell pIds = pIds_iter->second;
510 // GetSumm(pIds0,pIds,output);
513 // } // end new_faces_iter
515 // } // new_face2face_iter
519 TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin();
520 for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){
522 vtkIdType new_faceId = new_face2face_iter->first;
523 TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
524 vtkIdType fId0 = *new_faces_iter;
525 TCellArray::const_iterator pIds0_iter = f2points.find(fId0);
526 TCell pIds0 = pIds0_iter->second;
527 TCell &output = output_new_face2ids[new_faceId];
529 if(new_face2face_iter->second.size() == 1 ){
530 TCellArray::const_iterator pIds_iter = f2points.find(fId0);
531 TCell pIds = pIds_iter->second;
535 for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
537 vtkIdType faceId = *new_faces_iter;
538 // find how much nodes in face (f2points)
539 TCellArray::const_iterator pIds_iter = f2points.find(faceId);
540 TCell pIds = pIds_iter->second;
542 GetSumm(pIds0,pIds,output);
545 } // end new_faces_iter
547 } // new_face2face_iter
551 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
552 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
553 cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
555 outputCellArray = output_new_face2ids;//f2points;