Salome HOME
PAL10110 - incorrect title of dialog of file selection for file preference item
[modules/gui.git] / src / VTKViewer / VTKViewer_ConvexTool.cxx
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. 
5 // 
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 
9 // 
10 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
11
12 #include "VTKViewer_ConvexTool.h"
13
14 #include <vtkUnstructuredGrid.h>
15 #include <vtkTriangle.h>
16 #include <vtkConvexPointSet.h>
17 #include <vtkMath.h>
18
19 #include <set>
20 #include <iterator>
21 #include <algorithm>
22 #include <math.h>
23
24 typedef std::set<vtkIdType> TUIDS; // unique ids 
25 typedef std::map<vtkIdType,TUIDS> TPTOIDS; // id points -> unique ids
26
27 namespace CONVEX_TOOL
28 {
29
30 static float FACE_ANGLE_TOLERANCE=1.5;
31
32 #ifdef _DEBUG_
33   static int MYDEBUG = 0;
34 #else
35   static int MYDEBUG = 0;
36 #endif
37
38 /*! \fn static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center)
39  * \brief Calculation of geometry center.
40  * \param theGrid - vtkUnstructuredGrid cell.
41  * \param theptIds - point ids.
42  * \retval center - output array[3] with coordinates of geometry center.
43  */
44 static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center)
45 {
46   float *p;
47   center[0] = center[1] = center[2] = 0.0;
48   
49   int numIds=theptIds.size();
50
51   // get the center of the cell
52   for (int i=0; i < numIds; i++)
53     {
54       p = theGrid->GetPoint(theptIds[i]);
55       for (int j=0; j < 3; j++)
56         {
57           center[j] += p[j];
58         }
59     }
60   for (int j=0; j<3; j++)
61     {
62       center[j] /= numIds;
63     }
64 }
65
66 /*! \fn static void ReverseIds(TCell &theIds)
67  * \brief Reverse ids.
68  * \param theIds - points ids.
69  * \retval theIds - example input:(1,2,3,4) -> output:(4,3,2,1)
70  */
71 static void ReverseIds(TCell &theIds)
72 {
73   int i;
74   vtkIdType tmp;
75   vtkIdType npts=theIds.size();
76
77   for(i=0;i<(npts/2);i++){
78     tmp = theIds[i];
79     theIds[i] = theIds[npts-i-1];
80     theIds[npts-i-1] = tmp;
81   }
82 }
83
84 /*! \fn void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output)
85  * \brief Caclulation of connected faces (faceId -> (faceId1,faceId2, ...))
86  * \param p2faces - point to faces ids map.
87  * \param f2points - faces to points ids map.
88  * \retval face2face_output - faces to faces ids map.
89  */
90 void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output)
91 {
92   TCellArray::const_iterator f2pIter = f2points.begin();
93
94   for( ; f2pIter!=f2points.end() ; f2pIter++ ){
95     vtkIdType faceId = f2pIter->first;
96     TCell face_points = f2pIter->second;
97     int nb_face_points = face_points.size();
98     
99     vtkIdType id1;
100     vtkIdType id2;
101     TPTOIDS::const_iterator faces1;
102     TPTOIDS::const_iterator faces2;
103     
104     id1 = face_points[0];
105     faces1 = p2faces.find(id1);
106     
107     TUIDS output_faces;
108       
109     for(int i=1 ; i<nb_face_points ; i++ ){
110
111       id2 = face_points[i];
112
113       faces2 = p2faces.find(id2);
114       
115       std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(),
116         std::inserter(output_faces,output_faces.begin()));
117       
118       id1 = id2;
119       faces1 = faces2;
120     }
121     id1 = face_points[0];
122     faces1 = p2faces.find(id1);
123     std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(),
124       std::inserter(output_faces,output_faces.begin()));
125     
126     output_faces.erase(faceId); // erase the face id for which we found friends
127
128     if(MYDEBUG){
129       cout << "fId[" << faceId <<"]: ";
130       std::copy(output_faces.begin(), output_faces.end(), std::ostream_iterator<vtkIdType>(cout, " "));
131       cout << endl;
132     }
133     
134     face2face_output[faceId] = output_faces;
135   }
136 }
137
138 /*! \fn bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid,vtkIdType theFId1, vtkIdType theFId2,TUIDS FpIds1, TUIDS FpIds2 )
139  * \brief Check is connected faces on one plane.
140  * \param theGrid - vtkUnstructuredGrid
141  * \param theFId1 - id of first face
142  * \param theFId2 - id of second face
143  * \param FpIds1  - first face points ids.
144  * \param FpIds2  - second face points ids.
145  * \return TRUE if two faces on one plane, else FALSE.
146  */
147 bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid,
148                                  vtkIdType theFId1, vtkIdType theFId2,
149                                  TUIDS FpIds1, TUIDS FpIds2 )
150 {
151   bool status = false;
152   TUIDS common_ids;
153   std::set_intersection(FpIds1.begin(), FpIds1.end(), FpIds2.begin(), FpIds2.end(),
154                         std::inserter(common_ids,common_ids.begin()));
155   
156   /*           Number of common ids = 2 (A1,A2)
157                
158   
159                 _ _ _ _ _      _ _ _ _    vectors:
160                |         \   /         |   v1 {A2,A1}
161                           \ /              v2 {A1,B1}
162                |           | A2        |   v3 {A1,C1}
163                            |               
164                |           |           |
165                            |
166                |           | A1        |
167                           / \
168                |_ _ _ _ _/   \_ _ _ _ _|
169                B2        B1   C1        C2
170
171    */
172   TUIDS::iterator common_iter = common_ids.begin();
173   if(common_ids.size() == 2){
174     TUIDS::iterator loc_id1_0 = FpIds1.find(*(common_iter));
175     common_iter++;
176     TUIDS::iterator loc_id1_1 = FpIds1.find(*(common_iter));
177
178     TUIDS::iterator loc_id2_0 = FpIds1.begin();
179     TUIDS::iterator loc_id2_1 = FpIds2.begin();
180
181     vtkIdType A1 = *loc_id1_0;
182     vtkIdType A2 = *loc_id1_1;
183     vtkIdType B1;
184     vtkIdType C1;
185
186     for(;loc_id2_0!=FpIds1.end();loc_id2_0++)
187       if(*loc_id2_0 != A1 && *loc_id2_0!= A2){
188         B1 = *loc_id2_0;
189         break;
190       }
191     for(;loc_id2_1!=FpIds2.end();loc_id2_1++)
192       if(*loc_id2_1 != A1 && *loc_id2_1!= A2){
193         C1 = *loc_id2_1;
194         break;
195       }
196     if(MYDEBUG) cout <<endl;
197     if(MYDEBUG) cout << "FId_1="<<theFId1<<" FId_2="<<theFId2<<endl;
198     if(MYDEBUG) cout << "   A1="<<A1<<" A2="<<A2<<" B1="<<B1<<" C1="<<C1<<" ->";
199     float *p[4];
200     float v1[3],v2[3],v3[3];
201     p[0] = theGrid->GetPoint(A1);
202     p[1] = theGrid->GetPoint(A2);
203     p[2] = theGrid->GetPoint(B1);
204     p[3] = theGrid->GetPoint(C1);
205
206     for(int i=0;i<3;i++){
207       v1[i] = p[1][i] - p[0][i];
208       v2[i] = p[2][i] - p[0][i];
209       v3[i] = p[3][i] - p[0][i];
210     }
211     
212     
213     float vec_b1[3];
214     vtkMath::Cross(v2,v1,vec_b1);
215     float vec_b2[3];
216     vtkMath::Cross(v1,v3,vec_b2);
217
218     float b1 = vtkMath::Norm(vec_b1);
219
220     float b2 = vtkMath::Norm(vec_b2);
221     float aCos = vtkMath::Dot(vec_b1,vec_b2)/(b1*b2);
222     
223     float angle=90.0;
224     angle = aCos>=1.0 ? 0.0 : 180*acosf(aCos)/vtkMath::Pi();
225     
226     if( angle <= FACE_ANGLE_TOLERANCE)
227       status = true;
228     if (MYDEBUG){
229       for(int k=0;k<4;k++){
230         cout << " (";
231         for(int j=0;j<2;j++){
232           cout << p[k][j] << ",";
233         }
234         cout << p[k][2] << ")   ";
235       }
236       cout << "angle="<<angle<<" status="<<status<<endl;
237     }
238     
239   } else if (common_ids.size() >2){
240     // not implemented yet
241     if(MYDEBUG) cout << "Warning! VTKViewer_ConvexTool::IsConnectedFacesOnOnePlane()";
242   } else {
243     // one or no connection ... continue
244   }
245   
246   return status;
247 }
248
249 /*! \fn void GetAllFacesOnOnePlane( TPTOIDS theFaces, vtkIdType faceId,TUIDS &new_faces, TCell &new_faces_v2 )
250  * \brief Calculate faces which on one plane.
251  * \param theFaces - 
252  * \param faceId - 
253  * \param new_faces - 
254  * \param new_faces_v2 - 
255  */
256 void GetAllFacesOnOnePlane( TPTOIDS theFaces, vtkIdType faceId, 
257                             TUIDS &new_faces, TCell &new_faces_v2 )
258 {
259   if (new_faces.find(faceId) != new_faces.end()) return;
260   
261   new_faces.insert(new_faces.begin(),faceId);
262   new_faces_v2.push_back(faceId);
263
264   TPTOIDS::const_iterator aIter1 = theFaces.find(faceId);
265   if(aIter1!=theFaces.end()){
266     TUIDS::const_iterator aIter2 = (aIter1->second).begin();
267     for(;aIter2!=(aIter1->second).end();aIter2++){
268       if (new_faces.find(*aIter2) != new_faces.end()) continue;
269       GetAllFacesOnOnePlane(theFaces,*aIter2,
270                             new_faces,new_faces_v2); // recurvise
271     }
272   }
273   return;
274 }
275
276 /*! \fn void GetSumm(TCell v1,TCell v2,TCell &output)
277  * \brief Gluing two faces (gluing points ids)
278  * \param v1 - first face
279  * \param v2 - second face
280  * \param output - output face.
281  */
282 void GetSumm(TCell v1,TCell v2,TCell &output)
283 {
284   output.clear();
285
286   if(MYDEBUG) cout << "========================================="<<endl;
287   if(MYDEBUG) cout << "v1:";
288   if(MYDEBUG) std::copy(v1.begin(), v1.end(), std::ostream_iterator<vtkIdType>(cout, " "));
289   if(MYDEBUG) cout << "\tv2:";
290   if(MYDEBUG) std::copy(v2.begin(), v2.end(), std::ostream_iterator<vtkIdType>(cout, " "));
291   if(MYDEBUG) cout << endl;
292   
293   TUIDS v1_set;
294   std::copy(v1.begin(), v1.end(), std::inserter(v1_set,v1_set.begin()));
295   TUIDS v2_set;
296   std::copy(v2.begin(), v2.end(), std::inserter(v2_set,v2_set.begin()));
297   TUIDS tmpIntersection;
298   std::set_intersection(v1_set.begin(),v1_set.end(),v2_set.begin(),v2_set.end(), std::inserter(tmpIntersection,tmpIntersection.begin()));
299   if(MYDEBUG) std::copy(tmpIntersection.begin(),tmpIntersection.end(), std::ostream_iterator<vtkIdType>(cout, " "));
300   if(MYDEBUG) cout << endl;
301
302   if(tmpIntersection.size() < 2)
303     if(MYDEBUG) cout << __FILE__ << "[" << __LINE__ << "]: Warning ! Wrong ids" << endl;
304   
305   TCell::iterator v1_iter = v1.begin();
306   
307   for(;v1_iter!=v1.end();v1_iter++){
308     
309     vtkIdType curr_id = *v1_iter;
310     
311     output.push_back(curr_id);
312     
313     if(tmpIntersection.find(curr_id) != tmpIntersection.end()){
314       TCell::iterator v1_iter_tmp;
315       v1_iter_tmp = v1_iter;
316       v1_iter++;
317  
318       if(v1_iter==v1.end()) v1_iter=v1.begin();
319
320       curr_id = *v1_iter;
321
322       if(tmpIntersection.find(curr_id) != tmpIntersection.end()){
323         TCell::iterator v2_iter = v2.begin();
324         for(;v2_iter!=v2.end();v2_iter++){
325           vtkIdType v2_id = *v2_iter;
326           if(tmpIntersection.find(v2_id) == tmpIntersection.end())
327             output.push_back(v2_id);
328         }
329       }
330       
331       v1_iter = v1_iter_tmp;
332       curr_id = *v1_iter;
333       
334     }
335   }
336
337   if(MYDEBUG) cout << "Result: " ;
338   if(MYDEBUG) std::copy(output.begin(),output.end(),std::ostream_iterator<vtkIdType>(cout, " "));
339   if(MYDEBUG) cout << endl;
340 }
341
342 void GetPolygonalFaces(vtkUnstructuredGrid* theGrid,int cellId,TCellArray &outputCellArray)
343 {
344   if (theGrid->GetCellType(cellId) == VTK_CONVEX_POINT_SET){
345     // get vtkCell type = VTK_CONVEX_POINT_SET
346     if(vtkConvexPointSet* convex = static_cast<vtkConvexPointSet*>(theGrid->GetCell(cellId))){
347       TCellArray f2points;
348       float convex_center[3]; // convex center point coorinat
349       int aNbFaces = convex->GetNumberOfFaces();
350       int numPts = convex->GetNumberOfPoints();
351       TCell convex_ids;
352       TPTOIDS p2faces; // key=pointId , value facesIds set
353       
354       for(int i=0;i<numPts;i++)
355           convex_ids.push_back(convex->GetPointId(i));
356       
357       GetCenter(theGrid,convex_ids,convex_center);
358
359       for (vtkIdType faceId=0; faceId < aNbFaces; faceId++){
360         vtkCell *aFace = convex->GetFace(faceId);
361         int numFacePts = aFace->GetNumberOfPoints();
362         TCell aIds;
363         
364   int i = 0;
365         for(i=0;i<numFacePts;i++)
366           aIds.push_back(aFace->GetPointId(i));
367
368         float v_a[3],v_b[3],v_convex2face[3]; // vectors
369         float *id_0,*id_1,*id_n;
370         /*=============================================
371                         ,+- - - -  _
372                    _   / id_n   |  v_b {id_0,id_n}
373                   v_b /            _
374                      /          |  v_a {id_0,id_1}
375                     /          
376                    /            |
377                   + id_0
378                    \
379                   _ \           |
380                  v_a \
381                       \ id_1    |
382                        "+- - - -
383
384          ============================================*/ 
385         id_0 = theGrid->GetPoint(aIds[0]);
386         id_1 = theGrid->GetPoint(aIds[1]);
387         id_n = theGrid->GetPoint(aIds[numFacePts-1]);
388
389         for(i=0;i<3;i++){
390           v_a[i] = id_1[i] - id_0[i];
391           v_b[i] = id_n[i] - id_0[i];
392           v_convex2face[i] = id_0[i] - convex_center[i];
393         }
394
395         if (vtkMath::Determinant3x3(v_a,v_b,v_convex2face) < 0){
396           ReverseIds(aIds);
397         }
398
399         for(i=0;i<(int)aIds.size();i++){
400           TUIDS &acell = p2faces[aIds[i]];
401           acell.insert(faceId);
402         }
403         
404         f2points[faceId] = aIds;
405
406       }
407       
408       TPTOIDS face2face;
409       GetFriends(p2faces,f2points,face2face);
410       
411       TPTOIDS face2points;
412       
413       // copy TCellArray::f2points to TPTOIDS::face2points
414       for(TCellArray::iterator f2points_iter=f2points.begin();
415           f2points_iter!=f2points.end();
416           f2points_iter++){
417         
418         TUIDS tmp;
419         for(TCell::iterator points_iter=(f2points_iter->second).begin();
420             points_iter!=(f2points_iter->second).end();
421             points_iter++)
422           tmp.insert(*points_iter);
423         
424         face2points[f2points_iter->first] = tmp;
425       } // end copy
426         
427       
428       TPTOIDS new_face2faces; // which connected and in one plane
429       
430       TPTOIDS::const_iterator aF2FIter = face2face.begin();
431       for(;aF2FIter!=face2face.end();aF2FIter++){
432         vtkIdType f_key = aF2FIter->first;
433         TUIDS &faces = new_face2faces[f_key];
434         //faces.insert(f_key);
435         TUIDS f_friends = aF2FIter->second;
436         TUIDS::const_iterator a_friends_iter = f_friends.begin();
437         for(;a_friends_iter!=f_friends.end();a_friends_iter++){
438           vtkIdType friend_id = *a_friends_iter;
439           if( IsConnectedFacesOnOnePlane(theGrid,f_key,friend_id,
440                                         (face2points.find(f_key))->second,
441                                         (face2points.find(friend_id))->second)){
442             faces.insert(friend_id);
443           } // end if
444           
445         } // end a_friends_iter
446       } // end aF2FIter
447       
448       if(MYDEBUG)
449       {
450         TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin();
451         cout << "Connected faces and on plane:" << endl;
452         for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){
453           cout << "Group ["<<new_face2face_iter->first<<"] :";
454           TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
455           for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
456             cout << " " << *new_faces_iter ;
457           cout << endl;
458         }
459       }
460       
461       TPTOIDS output_newid2face;
462       TCellArray output_newid2face_v2;
463       {
464         TUIDS already_in;
465         TUIDS already_in_tmp;
466         int k=0;
467         TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin();
468         for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){
469           if(already_in.find(new_face2face_iter->first) != already_in.end())
470             continue;
471           if(new_face2face_iter->second.size() > 1)
472             continue;
473           
474           TCell &tmp_v2 = output_newid2face_v2[k];
475           tmp_v2.push_back(new_face2face_iter->first);
476           already_in.insert(new_face2face_iter->first);
477           
478           TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
479           for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
480             if(already_in.find(*new_faces_iter) != already_in.end()) continue;
481             already_in.insert(*new_faces_iter);
482             
483             already_in_tmp.clear();
484             already_in_tmp.insert(new_face2face_iter->first);
485
486             TUIDS &tmp = output_newid2face[k];
487             GetAllFacesOnOnePlane(new_face2faces,*new_faces_iter,
488                                   already_in_tmp,tmp_v2);
489             
490             for(TUIDS::const_iterator aIter=already_in_tmp.begin();
491                 aIter!=already_in_tmp.end();
492                 aIter++)
493               {
494                 already_in.insert(*aIter);
495                 tmp.insert(*aIter);
496               }
497           }
498           k++;
499         }
500       }
501       
502       if(MYDEBUG) {
503         cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
504         {
505           TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin();
506           for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){
507             cout << "Group ["<<new_face2face_iter->first<<"] :";
508             TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
509             for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
510               cout << " " << *new_faces_iter ;
511             cout << endl;
512           }
513         }
514         cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
515         cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
516         cout << "+++++++++++++++++++++++ ++ ++ ++++++++++++++++++++++++++++"<<endl;
517         cout << "+++++++++++++++++++++++++   ++++++++++++++++++++++++++++++"<<endl;
518         cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<<endl;
519         {
520           TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin();
521           for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){
522             cout << "Group ["<<new_face2face_iter->first<<"] :";
523             TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
524             for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++)
525               cout << " " << *new_faces_iter ;
526             cout << endl;
527           }
528         }
529       }
530       TCellArray output_new_face2ids;
531 //       {
532 //      TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin();
533 //      for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){
534           
535 //        vtkIdType new_faceId = new_face2face_iter->first;
536 //        TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
537 //        vtkIdType fId0 = *new_faces_iter;
538 //        TCellArray::const_iterator pIds0_iter = f2points.find(fId0);
539 //        TCell pIds0 = pIds0_iter->second;
540 //        TCell &output = output_new_face2ids[new_faceId];
541 //        new_faces_iter++;
542 //        if(new_face2face_iter->second.size() > 2 ){}
543 //        for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
544             
545 //          vtkIdType faceId = *new_faces_iter;
546 //          // find how much nodes in face (f2points)
547 //          TCellArray::const_iterator pIds_iter = f2points.find(faceId);
548 //          TCell pIds = pIds_iter->second;
549             
550 //          GetSumm(pIds0,pIds,output);
551 //          pIds0 = output;
552
553 //        } // end new_faces_iter
554           
555 //      } // new_face2face_iter
556 //       }
557       
558       {
559         TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin();
560         for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){
561           
562           vtkIdType new_faceId = new_face2face_iter->first;
563           TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin();
564           vtkIdType fId0 = *new_faces_iter;
565           TCellArray::const_iterator pIds0_iter = f2points.find(fId0);
566           TCell pIds0 = pIds0_iter->second;
567           TCell &output = output_new_face2ids[new_faceId];
568           new_faces_iter++;
569           if(new_face2face_iter->second.size() == 1 ){
570             TCellArray::const_iterator pIds_iter = f2points.find(fId0);
571             TCell pIds = pIds_iter->second;
572             output = pIds;
573             continue;
574           }
575           for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){
576             
577             vtkIdType faceId = *new_faces_iter;
578             // find how much nodes in face (f2points)
579             TCellArray::const_iterator pIds_iter = f2points.find(faceId);
580             TCell pIds = pIds_iter->second;
581             
582             GetSumm(pIds0,pIds,output);
583             pIds0 = output;
584
585           } // end new_faces_iter
586           
587         } // new_face2face_iter
588       }
589       
590       if(MYDEBUG) {
591         cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
592         cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
593         cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
594       }
595       outputCellArray = output_new_face2ids;//f2points;
596     }
597   } else {
598     // not implemented
599   }
600 }
601 }