From adf539355e380e249b26cca04018288462dc45f0 Mon Sep 17 00:00:00 2001 From: enk Date: Fri, 30 Dec 2005 09:26:03 +0000 Subject: [PATCH] Fix for Bug IPAL10939 Incorrect presentation of a polyhedral mesh volume --- src/VTKViewer/VTKViewer_ConvexTool.cxx | 304 +++++++++++++++++++++++-- src/VTKViewer/VTKViewer_ConvexTool.h | 2 + 2 files changed, 288 insertions(+), 18 deletions(-) diff --git a/src/VTKViewer/VTKViewer_ConvexTool.cxx b/src/VTKViewer/VTKViewer_ConvexTool.cxx index 1bb641de8..a4dded2cc 100644 --- a/src/VTKViewer/VTKViewer_ConvexTool.cxx +++ b/src/VTKViewer/VTKViewer_ConvexTool.cxx @@ -32,45 +32,62 @@ #include #include #include +#include #include +#include #include #include #include #include +typedef vtkUnstructuredGrid TInput; + typedef std::set TUIDS; // unique ids typedef std::map TPTOIDS; // id points -> unique ids namespace CONVEX_TOOL { + void + WriteToFile(vtkUnstructuredGrid* theDataSet, const std::string& theFileName) + { + vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); + aWriter->SetFileName(theFileName.c_str()); + aWriter->SetInput(theDataSet); + aWriter->Write(); + aWriter->Delete(); + } static float FACE_ANGLE_TOLERANCE=1.5; +#define EPS 1.0e-38 +#define EPS_T 1.0e-3 #ifdef _DEBUG_ static int MYDEBUG = 0; + static int MYDEBUG_REMOVE = 0; #else static int MYDEBUG = 0; + static int MYDEBUG_REMOVE = 0; #endif -/*! \fn static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float *center) +/*! \fn static void GetCenter(TInput* theGrid,TCell theptIds,float *center) * \brief Calculation of geometry center. - * \param theGrid - vtkUnstructuredGrid cell. + * \param theGrid - TInput cell. * \param theptIds - point ids. * \retval center - output array[3] with coordinates of geometry center. */ -static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float center[3]) +static void GetCenter(vtkPoints* thePoints,float center[3]) { float p[3]; center[0] = center[1] = center[2] = 0.0; - int numIds = theptIds.size(); - if (numIds == 0) return; + int numPts = thePoints->GetNumberOfPoints(); + if (numPts == 0) return; // get the center of the cell - for (int i = 0; i < numIds; i++) + for (int i = 0; i < numPts; i++) { - theGrid->GetPoint(theptIds[i], p); + thePoints->GetPoint(i, p); for (int j = 0; j < 3; j++) { center[j] += p[j]; @@ -78,7 +95,7 @@ static void GetCenter(vtkUnstructuredGrid* theGrid,TCell theptIds,float center[3 } for (int j = 0; j < 3; j++) { - center[j] /= numIds; + center[j] /= numPts; } } @@ -154,16 +171,16 @@ void GetFriends(const TPTOIDS p2faces,const TCellArray f2points,TPTOIDS& face2fa } } -/*! \fn bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid,vtkIdType theFId1, vtkIdType theFId2,TUIDS FpIds1, TUIDS FpIds2 ) +/*! \fn bool IsConnectedFacesOnOnePlane( TInput* theGrid,vtkIdType theFId1, vtkIdType theFId2,TUIDS FpIds1, TUIDS FpIds2 ) * \brief Check is connected faces on one plane. - * \param theGrid - vtkUnstructuredGrid + * \param theGrid - TInput * \param theFId1 - id of first face * \param theFId2 - id of second face * \param FpIds1 - first face points ids. * \param FpIds2 - second face points ids. * \return TRUE if two faces on one plane, else FALSE. */ -bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid, +bool IsConnectedFacesOnOnePlane( TInput* theGrid, vtkIdType theFId1, vtkIdType theFId2, TUIDS FpIds1, TUIDS FpIds2 ) { @@ -252,7 +269,7 @@ bool IsConnectedFacesOnOnePlane( vtkUnstructuredGrid* theGrid, } cout << p[k][2] << ") "; } - cout << "angle="<GetPoint(current_points_ids[0],P[0]); + points->GetPoint(current_points_ids[1],P[1]); + TUIDS::iterator aPointsIter = input_points_ids.begin(); + for(;aPointsIter!=input_points_ids.end();aPointsIter++){ + if(iscurrent_points_changed){ + points->GetPoint(current_points_ids[0],P[0]); + points->GetPoint(current_points_ids[1],P[1]); + iscurrent_points_changed = false; + if (MYDEBUG_REMOVE) + cout << " " << current_points_ids[0] << " " << current_points_ids[1] << endl; + } + // check: is point on line input_two_points_ids + points->GetPoint(*aPointsIter,P[2]); + if (MYDEBUG_REMOVE) { + cout << "\t" << current_points_ids[0] << ":"< coeff[0][0] = (x-x1), coeff[0][1] = x2-x1 + // y-y1=(y2-y1)*t -> coeff[1][0] = (y-y1), coeff[1][1] = y2-y1 + // z-z1=(z2-z1)*t -> coeff[2][0] = (z-z1), coeff[2][1] = z2-z1 + float coeff[3][2]; + for(int i=0;i<3;i++){ + coeff[i][0] = P[2][i]-P[0][i]; + coeff[i][1] = P[1][i]-P[0][i]; + } + bool isok_coord[3]; + bool isok = true; + float t[3]; + for(int i=0;i<3;i++){ + isok_coord[i] = false; + if( fabs(coeff[i][0]) <= EPS && fabs(coeff[i][1]) <= EPS) { + isok_coord[i] = true; + continue; + } + if( fabs(coeff[i][1]) <= EPS && fabs(coeff[i][0]) > EPS) {isok = false;t[i]=1.0/EPS;break;} + t[i] = (coeff[i][0])/(coeff[i][1]); + } + for(int i=0;i<3;i++) + if (MYDEBUG_REMOVE) + cout << __LINE__ << " " + << coeff[i][0] << ","<t[0],t[1],t[2] + // anilize bounds of line + for(int i=0;i<3;i++){ + for(int j=0;j<3;j++) + if(!isok_coord[j]) param[i] = (P[i][j]-P[0][j])/(P[1][j]-P[0][j]); + } + if (MYDEBUG_REMOVE) cout << "Params: " << param[0] << "," << param[1] << "," << param[2] << endl; + vtkIdType imax,imin; + float min,max; + for(vtkIdType i=0;i<3;i++) + if(!isok_coord[i]){ + min = param[0];imin=0; + max = param[0];imax=0; + break; + } + for(vtkIdType i=0;i<3;i++){ + if(min > param[i]) {min = param[i]; imin=i;} + if(max < param[i]) {max = param[i]; imax=i;} + } + if (MYDEBUG_REMOVE) + cout << "\t min="<"< out = vtkConvexPointSet::New(); + + TUIDS two_points,input_points,out_two_points_ids,removed_points_ids,loc_removed_points_ids; + vtkIdList* aPointIds = convex->GetPointIds(); + int numIds = aPointIds->GetNumberOfIds(); + // all pairs + typedef std::pair TPair; + typedef std::set TSet; + TSet good_point_ids; + TSet aLists[numIds-2]; + for(int i=0;iGetId(aFirId) << "," << aSecId <<":"<GetId(aSecId)<< " --- "; + for(vtkIdType k=aSecId+1;kGetId(k) << ","; + } + if (MYDEBUG_REMOVE) { + cout << endl; + cout << "\t"; + for(TUIDS::iterator aDelIter = loc_removed_points_ids.begin();aDelIter!=loc_removed_points_ids.end();aDelIter++) + cout << *aDelIter<<","; + cout << endl; + } + GetAndRemoveIdsOnOneLine(convex->Points, + input_points, + two_points, + out_two_points_ids, + loc_removed_points_ids); + TUIDS::iterator aOutIter = out_two_points_ids.begin(); + vtkIdType aFirst=*aOutIter;aOutIter++;vtkIdType aSecond=*aOutIter; + TPair aPair(aFirst,aSecond); + good_point_ids.insert(aPair); + if (MYDEBUG_REMOVE){ + cout << "Output: "; + TUIDS::iterator aIter = out_two_points_ids.begin(); + for(;aIter!=out_two_points_ids.end();aIter++) + cout << *aIter << ","; + cout << " --- "; + } + TUIDS::iterator aDelIter = loc_removed_points_ids.begin(); + for(;aDelIter!=loc_removed_points_ids.end();aDelIter++){ + removed_points_ids.insert(*aDelIter); + if (MYDEBUG_REMOVE) cout << *aDelIter << ","; + } + if (MYDEBUG_REMOVE) cout << endl; + } + } + if (MYDEBUG_REMOVE) { + cout << "============ Resultat ================" <Points->SetNumberOfPoints(result_ids.size()); + out->PointIds->SetNumberOfIds(result_ids.size()); + int aId=0; + if(MYDEBUG_REMOVE) cout << "Result out:"; + for(TUIDS::iterator aIter=result_ids.begin();aIter!=result_ids.end();aIter++,aId++){ + float P[3]; + convex->Points->GetPoint(*aIter,P); + out->Points->SetPoint(aId,P); + out->PointIds->SetId(aId,aPointIds->GetId(*aIter)); + if (MYDEBUG_REMOVE) cout << *aIter << ":" << aPointIds->GetId(*aIter) << " , "; + } + if(MYDEBUG_REMOVE) cout << endl; + out->Modified(); + out->Initialize(); + + return out.GetPointer(); +} + 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))){ + if(vtkConvexPointSet* convex_in = static_cast(theGrid->GetCell(cellId))){ + vtkConvexPointSet* convex = RemoveAllUnneededPoints(convex_in); TCellArray f2points; float convex_center[3]; // convex center point coorinat int aNbFaces = convex->GetNumberOfFaces(); int numPts = convex->GetNumberOfPoints(); - TCell convex_ids; + if(MYDEBUG_REMOVE) cout << "aNbFaces="<