From 99de054178583522250679a94d7eeacc6ee37c7e Mon Sep 17 00:00:00 2001 From: enk Date: Tue, 26 Apr 2005 12:19:01 +0000 Subject: [PATCH] Added new files: SALOME_ConvexTool.h SALOME_ConvexTool.cxx which calculate polygones from triangles of vtkConvexPointSet using in SALOME_GeometryFilter.cxx --- src/VTKFilter/SALOME_ConvexTool.cxx | 561 ++++++++++++++++++++++++++++ src/VTKFilter/SALOME_ConvexTool.h | 47 +++ 2 files changed, 608 insertions(+) create mode 100644 src/VTKFilter/SALOME_ConvexTool.cxx create mode 100644 src/VTKFilter/SALOME_ConvexTool.h diff --git a/src/VTKFilter/SALOME_ConvexTool.cxx b/src/VTKFilter/SALOME_ConvexTool.cxx new file mode 100644 index 000000000..5fcf12f48 --- /dev/null +++ b/src/VTKFilter/SALOME_ConvexTool.cxx @@ -0,0 +1,561 @@ +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SALOME_ConvexTool.cxx +// Author : Eugeny Nikolaev +// Module : SALOME +// $Header$ + +#include "SALOME_ConvexTool.h" + +#include +#include +#include + +#include +#include +#include +#include + +static float FACE_TOLERANCE=0; + +typedef std::set TUIDS; // unique ids +typedef std::map TPTOIDS; // id points -> unique ids + + +namespace CONVEX_TOOL{ +#ifdef _DEBUG_ +static int MYDEBUG = 0; +#else +static int MYDEBUG = 0; +#endif + +static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center) +{ + float *p; + center[0] = center[1] = center[2] = 0.0; + + int numIds=theptIds.size(); + + // get the center of the cell + for (int i=0; i < numIds; i++) + { + p = theGrid->GetPoint(theptIds[i]); + for (int j=0; j < 3; j++) + { + center[j] += p[j]; + } + } + for (int j=0; j<3; j++) + { + center[j] /= numIds; + } +} + +static void ReverseIds(TCell &theIds){ + int i; + vtkIdType tmp; + vtkIdType npts=theIds.size(); + + for(i=0;i<(npts/2);i++){ + tmp = theIds[i]; + theIds[i] = theIds[npts-i-1]; + theIds[npts-i-1] = tmp; + } +} + +// caclulation of connected faces (faceId -> (faceId1,faceId2, ...)) +void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2face_output) +{ + TCellArray::const_iterator f2pIter = f2points.begin(); + + for( ; f2pIter!=f2points.end() ; f2pIter++ ){ + vtkIdType faceId = f2pIter->first; + TCell face_points = f2pIter->second; + int nb_face_points = face_points.size(); + + vtkIdType id1; + vtkIdType id2; + TPTOIDS::const_iterator faces1; + TPTOIDS::const_iterator faces2; + + id1 = face_points[0]; + faces1 = p2faces.find(id1); + + TUIDS output_faces; + + for(int i=1 ; isecond.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(), + inserter(output_faces,output_faces.begin())); + + id1 = id2; + faces1 = faces2; + } + id1 = face_points[0]; + faces1 = p2faces.find(id1); + std::set_intersection(faces1->second.begin(), faces1->second.end(), faces2->second.begin(), faces2->second.end(), + inserter(output_faces,output_faces.begin())); + + output_faces.erase(faceId); // erase the face id for which we found friends + + if(MYDEBUG){ + cout << "fId[" << faceId <<"]: "; + copy(output_faces.begin(), output_faces.end(), ostream_iterator(cout, " ")); + cout << endl; + } + + face2face_output[faceId] = output_faces; + } +} + +bool IsConnectedFacesOnOnePlane(vtkUnstructuredGrid* theGrid, + vtkIdType theFId1,vtkIdType theFId2, + TUIDS FpIds1,TUIDS FpIds2) +{ + bool status = false; + TUIDS common_ids; + std::set_intersection(FpIds1.begin(), FpIds1.end(), FpIds2.begin(), FpIds2.end(), + inserter(common_ids,common_ids.begin())); + + /* Number of common ids = 2 (A1,A2) + + + _ _ _ _ _ _ _ _ _ vectors: + | \ / | v1 {A2,A1} + \ / v2 {A1,B1} + | | A2 | v3 {A1,C1} + | + | | | + | + | | A1 | + / \ + |_ _ _ _ _/ \_ _ _ _ _| + B2 B1 C1 C2 + + */ + TUIDS::iterator common_iter = common_ids.begin(); + if(common_ids.size() == 2){ + TUIDS::iterator loc_id1_0 = FpIds1.find(*(common_iter)); + common_iter++; + TUIDS::iterator loc_id1_1 = FpIds1.find(*(common_iter)); + + TUIDS::iterator loc_id2_0 = FpIds1.begin(); + TUIDS::iterator loc_id2_1 = FpIds2.begin(); + + vtkIdType A1 = *loc_id1_0; + vtkIdType A2 = *loc_id1_1; + vtkIdType B1,B2; + vtkIdType C1,C2; + + for(;loc_id2_0!=FpIds1.end();loc_id2_0++) + if(*loc_id2_0 != A1 && *loc_id2_0!= A2){ + B1 = *loc_id2_0; + break; + } + for(;loc_id2_1!=FpIds2.end();loc_id2_1++) + if(*loc_id2_1 != A1 && *loc_id2_1!= A2){ + C1 = *loc_id2_1; + break; + } + if(MYDEBUG) cout <"; + float *p[4]; + float v1[3],v2[3],v3[3]; + p[0] = theGrid->GetPoint(A1); + p[1] = theGrid->GetPoint(A2); + p[2] = theGrid->GetPoint(B1); + p[3] = theGrid->GetPoint(C1); + + for(int i=0;i<3;i++){ + v1[i] = p[1][i] - p[0][i]; + v2[i] = p[2][i] - p[0][i]; + v3[i] = p[3][i] - p[0][i]; + } + + + float det = vtkMath::Determinant3x3(v1,v2,v3); +// float det = v1[0]*(v2[1]*v3[2]-v2[2]*v3[1]) - +// v1[1]*(v2[0]*v3[2]-v2[2]*v3[0]) + +// v1[2]*(v2[0]*v3[1]-v2[1]*v3[0]); + if(det < 0) + det = -det; + + if( det <= FACE_TOLERANCE ) + status = true; + if (MYDEBUG){ + for(int k=0;k<4;k++){ + cout << " ("; + for(int j=0;j<2;j++){ + cout << p[k][j] << ","; + } + cout << p[k][2] << ") "; + } + cout << endl; + } + + } else if (common_ids.size() >2){ + // not implemented yet + if(MYDEBUG) cout << "Warning! SALOME_ConvexTool::IsConnectedFacesOnOnePlane()"; + } else { + // one or no connection ... continue + } + + return status; +} + +void GetAllFacesOnOnePlane(TPTOIDS theFaces, vtkIdType faceId, + TUIDS &new_faces,TCell &new_faces_v2){ + + if (new_faces.find(faceId) != new_faces.end()) return; + + new_faces.insert(new_faces.begin(),faceId); + new_faces_v2.push_back(faceId); + + TPTOIDS::const_iterator aIter1 = theFaces.find(faceId); + if(aIter1!=theFaces.end()){ + TUIDS::const_iterator aIter2 = (aIter1->second).begin(); + for(;aIter2!=(aIter1->second).end();aIter2++){ + if (new_faces.find(*aIter2) != new_faces.end()) continue; + GetAllFacesOnOnePlane(theFaces,*aIter2, + new_faces,new_faces_v2); // recurvise + } + } + return; +} + +void GetSumm(TCell v1,TCell v2,TCell &output){ + + output.clear(); + + if(MYDEBUG) cout << "========================================="<(cout, " ")); + if(MYDEBUG) cout << "\tv2:"; + if(MYDEBUG) copy(v2.begin(), v2.end(), ostream_iterator(cout, " ")); + if(MYDEBUG) cout << endl; + + TUIDS v1_set; + copy(v1.begin(), v1.end(), inserter(v1_set,v1_set.begin())); + TUIDS v2_set; + copy(v2.begin(), v2.end(), inserter(v2_set,v2_set.begin())); + TUIDS tmpIntersection; + set_intersection(v1_set.begin(),v1_set.end(),v2_set.begin(),v2_set.end(),inserter(tmpIntersection,tmpIntersection.begin())); + if(MYDEBUG) copy(tmpIntersection.begin(),tmpIntersection.end(),ostream_iterator(cout, " ")); + if(MYDEBUG) cout << endl; + + if(tmpIntersection.size() < 2) + if(MYDEBUG) cout << __FILE__ << "[" << __LINE__ << "]: Warning ! Wrong ids" << endl; + + TCell::iterator v1_iter = v1.begin(); + + for(;v1_iter!=v1.end();v1_iter++){ + + vtkIdType curr_id = *v1_iter; + + output.push_back(curr_id); + + if(tmpIntersection.find(curr_id) != tmpIntersection.end()){ + TCell::iterator v1_iter_tmp; + v1_iter_tmp = v1_iter; + v1_iter++; + + if(v1_iter==v1.end()) v1_iter=v1.begin(); + + curr_id = *v1_iter; + + if(tmpIntersection.find(curr_id) != tmpIntersection.end()){ + TCell::iterator v2_iter = v2.begin(); + for(;v2_iter!=v2.end();v2_iter++){ + vtkIdType v2_id = *v2_iter; + if(tmpIntersection.find(v2_id) == tmpIntersection.end()) + output.push_back(v2_id); + } + } + + v1_iter = v1_iter_tmp; + curr_id = *v1_iter; + + } + } + + if(MYDEBUG) cout << "Result: " ; + if(MYDEBUG) copy(output.begin(),output.end(),ostream_iterator(cout, " ")); + if(MYDEBUG) cout << endl; +} + +void GetPolygonalFaces(vtkUnstructuredGrid* theGrid,int cellId,TCellArray &outputCellArray) +{ + if (theGrid->GetCellType(cellId) == VTK_CONVEX_POINT_SET){ + // get vtkCell type = VTK_CONVEX_POINT_SET + if(vtkConvexPointSet* convex = static_cast(theGrid->GetCell(cellId))){ + TCellArray f2points; + float convex_center[3]; // convex center point coorinat + int aNbFaces = convex->GetNumberOfFaces(); + int numPts = convex->GetNumberOfPoints(); + TCell convex_ids; + TPTOIDS p2faces; // key=pointId , value facesIds set + + for(int i=0;iGetPointId(i)); + + GetCenter(theGrid,convex_ids,convex_center); + + for (vtkIdType faceId=0; faceId < aNbFaces; faceId++){ + vtkCell *aFace = convex->GetFace(faceId); + int numFacePts = aFace->GetNumberOfPoints(); + TCell aIds; + + for(int i=0;iGetPointId(i)); + + float v_a[3],v_b[3],v_convex2face[3]; // vectors + float *id_0,*id_1,*id_n; + /*============================================= + ,+- - - - _ + _ / id_n | v_b {id_0,id_n} + v_b / _ + / | v_a {id_0,id_1} + / + / | + + id_0 + \ + _ \ | + v_a \ + \ id_1 | + "+- - - - + + ============================================*/ + id_0 = theGrid->GetPoint(aIds[0]); + id_1 = theGrid->GetPoint(aIds[1]); + id_n = theGrid->GetPoint(aIds[numFacePts-1]); + + for(int i=0;i<3;i++){ + v_a[i] = id_1[i] - id_0[i]; + v_b[i] = id_n[i] - id_0[i]; + v_convex2face[i] = id_0[i] - convex_center[i]; + } + + if (vtkMath::Determinant3x3(v_a,v_b,v_convex2face) < 0){ + ReverseIds(aIds); + } + + for(int i=0;isecond).begin(); + points_iter!=(f2points_iter->second).end(); + points_iter++) + tmp.insert(*points_iter); + + face2points[f2points_iter->first] = tmp; + } // end copy + + + TPTOIDS new_face2faces; // which connected and in one plane + int count=0; + + TPTOIDS::const_iterator aF2FIter = face2face.begin(); + for(;aF2FIter!=face2face.end();aF2FIter++){ + vtkIdType f_key = aF2FIter->first; + TUIDS &faces = new_face2faces[f_key]; + //faces.insert(f_key); + TUIDS f_friends = aF2FIter->second; + TUIDS::const_iterator a_friends_iter = f_friends.begin(); + for(;a_friends_iter!=f_friends.end();a_friends_iter++){ + vtkIdType friend_id = *a_friends_iter; + if( IsConnectedFacesOnOnePlane(theGrid,f_key,friend_id, + (face2points.find(f_key))->second, + (face2points.find(friend_id))->second)){ + faces.insert(friend_id); + } // end if + + } // end a_friends_iter + } // end aF2FIter + + if(MYDEBUG) + { + TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin(); + cout << "Connected faces and on plane:" << endl; + for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){ + cout << "Group ["<first<<"] :"; + TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++) + cout << " " << *new_faces_iter ; + cout << endl; + } + } + + TPTOIDS output_newid2face; + TCellArray output_newid2face_v2; + { + TUIDS already_in; + TUIDS already_in_tmp; + int k=0; + TPTOIDS::const_iterator new_face2face_iter = new_face2faces.begin(); + for(;new_face2face_iter!=new_face2faces.end();new_face2face_iter++){ + if(already_in.find(new_face2face_iter->first) != already_in.end()) + continue; + if(new_face2face_iter->second.size() > 1) + continue; + + TCell &tmp_v2 = output_newid2face_v2[k]; + tmp_v2.push_back(new_face2face_iter->first); + already_in.insert(new_face2face_iter->first); + + TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){ + if(already_in.find(*new_faces_iter) != already_in.end()) continue; + already_in.insert(*new_faces_iter); + + already_in_tmp.clear(); + already_in_tmp.insert(new_face2face_iter->first); + + TUIDS &tmp = output_newid2face[k]; + GetAllFacesOnOnePlane(new_face2faces,*new_faces_iter, + already_in_tmp,tmp_v2); + + for(TUIDS::const_iterator aIter=already_in_tmp.begin(); + aIter!=already_in_tmp.end(); + aIter++) + { + already_in.insert(*aIter); + tmp.insert(*aIter); + } + } + k++; + } + } + + if(MYDEBUG) { + cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<first<<"] :"; + TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++) + cout << " " << *new_faces_iter ; + cout << endl; + } + } + cout << "++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++"<first<<"] :"; + TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++) + cout << " " << *new_faces_iter ; + cout << endl; + } + } + } + TCellArray output_new_face2ids; +// { +// TPTOIDS::const_iterator new_face2face_iter = output_newid2face.begin(); +// for(;new_face2face_iter!=output_newid2face.end();new_face2face_iter++){ + +// vtkIdType new_faceId = new_face2face_iter->first; +// TUIDS::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); +// vtkIdType fId0 = *new_faces_iter; +// TCellArray::const_iterator pIds0_iter = f2points.find(fId0); +// TCell pIds0 = pIds0_iter->second; +// TCell &output = output_new_face2ids[new_faceId]; +// new_faces_iter++; +// if(new_face2face_iter->second.size() > 2 ){} +// for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){ + +// vtkIdType faceId = *new_faces_iter; +// // find how much nodes in face (f2points) +// TCellArray::const_iterator pIds_iter = f2points.find(faceId); +// TCell pIds = pIds_iter->second; + +// GetSumm(pIds0,pIds,output); +// pIds0 = output; + +// } // end new_faces_iter + +// } // new_face2face_iter +// } + + { + TCellArray::const_iterator new_face2face_iter = output_newid2face_v2.begin(); + for(;new_face2face_iter!=output_newid2face_v2.end();new_face2face_iter++){ + + vtkIdType new_faceId = new_face2face_iter->first; + TCell::const_iterator new_faces_iter = (new_face2face_iter->second).begin(); + vtkIdType fId0 = *new_faces_iter; + TCellArray::const_iterator pIds0_iter = f2points.find(fId0); + TCell pIds0 = pIds0_iter->second; + TCell &output = output_new_face2ids[new_faceId]; + new_faces_iter++; + if(new_face2face_iter->second.size() == 1 ){ + TCellArray::const_iterator pIds_iter = f2points.find(fId0); + TCell pIds = pIds_iter->second; + output = pIds; + continue; + } + for(;new_faces_iter!=(new_face2face_iter->second).end();new_faces_iter++){ + + vtkIdType faceId = *new_faces_iter; + // find how much nodes in face (f2points) + TCellArray::const_iterator pIds_iter = f2points.find(faceId); + TCell pIds = pIds_iter->second; + + GetSumm(pIds0,pIds,output); + pIds0 = output; + + } // end new_faces_iter + + } // new_face2face_iter + } + + if(MYDEBUG) { + cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"< + +#include +#include + +typedef std::vector TCell; // ptsIds +typedef std::map TCellArray; // CellId, TCell + +namespace CONVEX_TOOL{ + + void GetPolygonalFaces(vtkUnstructuredGrid* theCell,int cellId,TCellArray &outputCellArray); +} + +#endif // _SALOME_ConvexTool_H + -- 2.39.2