d0f70db3c850f5c1edd9129b5af932556dc8b208
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_Check.cxx
1 // Created on: 1997-04-10
2 // Created by: Prestataire Mary FABIEN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <gp_Pnt.hxx>
20 #include <Standard_Type.hxx>
21 #include <TCollection_AsciiString.hxx>
22 #include <TColStd_IndexedMapOfInteger.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopOpeBRepDS.hxx>
27 #include <TopOpeBRepDS_Check.hxx>
28 #include <TopOpeBRepDS_CheckStatus.hxx>
29 #include <TopOpeBRepDS_CurvePointInterference.hxx>
30 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfCheckStatus.hxx>
31 #include <TopOpeBRepDS_DataMapOfCheckStatus.hxx>
32 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
33 #include <TopOpeBRepDS_HDataStructure.hxx>
34 #include <TopOpeBRepDS_Interference.hxx>
35 #include <TopOpeBRepDS_InterferenceTool.hxx>
36 #include <TopOpeBRepDS_Kind.hxx>
37 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
38 #include <TopOpeBRepDS_ListOfInterference.hxx>
39 #include <TopOpeBRepDS_PointExplorer.hxx>
40 #include <TopOpeBRepTool_ShapeTool.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42 #include <TopTools_ListOfShape.hxx>
43
44 #include <string.h>
45 IMPLEMENT_STANDARD_RTTIEXT(TopOpeBRepDS_Check,Standard_Transient)
46
47 //=======================================================================
48 //function : Create
49 //purpose  : 
50 //=======================================================================
51 TopOpeBRepDS_Check::TopOpeBRepDS_Check(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
52 {
53   myHDS = HDS;
54   myMapSurfaceStatus.Clear();
55   myMapCurveStatus.Clear();
56   myMapPointStatus.Clear();
57   myMapShapeStatus.Clear();
58 }
59
60 //=======================================================================
61 //function : Create
62 //purpose  : 
63 //=======================================================================
64
65 TopOpeBRepDS_Check::TopOpeBRepDS_Check()
66 {
67     myMapSurfaceStatus.Clear();
68     myMapCurveStatus.Clear();
69     myMapPointStatus.Clear();
70     myMapShapeStatus.Clear();
71 }
72
73 //=======================================================================
74 //function : ChkIntg
75 //purpose  : Check Integrity
76 //=======================================================================
77 Standard_Boolean CheckEdgeParameter(const Handle(TopOpeBRepDS_HDataStructure)& myHDS);
78 Standard_Boolean TopOpeBRepDS_Check::ChkIntg()
79 {
80   const TopOpeBRepDS_DataStructure& DS = myHDS->DS();
81   Standard_Boolean bI=Standard_False;
82   // Check the integrity of the DS
83   Standard_Integer i,nshape = DS.NbShapes();
84   for (i = 1; i <= nshape; i++) {
85     // Integrity of Interferences : Check support and geometry
86     const TopOpeBRepDS_ListOfInterference& LI = DS.ShapeInterferences(i);
87     bI = ChkIntgInterf(LI);
88   }
89   Standard_Integer nsurface = DS.NbSurfaces();
90   for (i = 1; i <= nsurface; i++) {
91     // Integrity of Interferences : Check support and geometry
92     const TopOpeBRepDS_ListOfInterference& LI = DS.SurfaceInterferences(i);
93     bI = bI && ChkIntgInterf(LI);
94   }
95   
96   Standard_Integer ncurve = DS.NbCurves();
97   for (i = 1; i <= ncurve; i++) {
98     // Integrity of Interferences : Check support and geometry
99     const TopOpeBRepDS_ListOfInterference& LI = DS.CurveInterferences(i);
100     bI = bI && ChkIntgInterf(LI);
101   }
102   
103   Standard_Integer npoint = DS.NbPoints();
104   for (i = 1; i <= npoint; i++) {
105     // Integrity of Interferences : Check support and geometry
106     const TopOpeBRepDS_ListOfInterference& LI = DS.PointInterferences(i);
107     bI = bI && ChkIntgInterf(LI);
108   }
109
110   //  CheckEdgeParameter();
111   CheckEdgeParameter(myHDS);
112
113   return bI;
114 }
115
116 //=======================================================================
117 //function : ChkIntgInterf
118 //purpose  : 
119 //=======================================================================
120
121 Standard_Boolean TopOpeBRepDS_Check::ChkIntgInterf
122 (const TopOpeBRepDS_ListOfInterference& LI)
123 {
124   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
125   it1.Initialize(LI);
126   Standard_Boolean IsOK = Standard_True;
127   while (it1.More() ) {
128     Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
129     IsOK = IsOK && CheckDS(I1->Support(), I1->SupportType());
130     IsOK = IsOK && CheckDS(I1->Geometry(), I1->GeometryType());
131     it1.Next();
132   }
133   return IsOK;
134
135
136 //=======================================================================
137 //function : CheckDS
138 //purpose  : 
139 //=======================================================================
140
141 Standard_Boolean TopOpeBRepDS_Check::CheckDS(const Standard_Integer I,
142                                              const TopOpeBRepDS_Kind K)
143 {
144   // geometry
145   switch(K) {
146   case TopOpeBRepDS_SURFACE :
147     {
148       if(myHDS->NbSurfaces() < I) {
149         if(myMapSurfaceStatus.IsBound(I))
150           myMapSurfaceStatus.UnBind(I);
151         myMapSurfaceStatus.Bind(I, TopOpeBRepDS_NOK);
152         return Standard_False;
153       }
154       if(!myMapSurfaceStatus.IsBound(I))
155         myMapSurfaceStatus.Bind(I,TopOpeBRepDS_OK);
156       return Standard_True;
157     }
158   case TopOpeBRepDS_CURVE :
159     {
160       if(myHDS->NbCurves() < I) {
161         if(myMapCurveStatus.IsBound(I))
162           myMapCurveStatus.UnBind(I);
163         myMapCurveStatus.Bind(I, TopOpeBRepDS_NOK);
164         return Standard_False;
165       }
166       
167       if(!myMapCurveStatus.IsBound(I))
168         myMapCurveStatus.Bind(I,TopOpeBRepDS_OK);
169       return Standard_True;
170     }
171   case TopOpeBRepDS_POINT :
172     {
173       if(myHDS->NbPoints() < I) {
174         if(myMapPointStatus.IsBound(I))
175           myMapPointStatus.UnBind(I);
176         myMapPointStatus.Bind(I, TopOpeBRepDS_NOK);
177         return Standard_False;
178       }
179       if(!myMapPointStatus.IsBound(I))
180         myMapPointStatus.Bind(I,TopOpeBRepDS_OK);
181       return Standard_True;
182     }
183   default:
184     break ;
185   }
186   
187
188   // topology
189   if(myHDS->NbShapes() < I) {
190     if(myMapShapeStatus.IsBound(I))
191       myMapShapeStatus.UnBind(I);
192     myMapShapeStatus.Bind(I,TopOpeBRepDS_NOK);
193     return Standard_False;
194   }
195   const TopoDS_Shape& S =myHDS->Shape(I);
196
197   TopAbs_ShapeEnum se=TopAbs_COMPOUND;
198
199   switch (K) {
200   case TopOpeBRepDS_SOLID  : se = TopAbs_SOLID; break;
201   case TopOpeBRepDS_SHELL  : se = TopAbs_SHELL; break;
202   case TopOpeBRepDS_FACE   : se = TopAbs_FACE;  break;
203   case TopOpeBRepDS_WIRE   : se = TopAbs_WIRE;  break;
204   case TopOpeBRepDS_EDGE   : se = TopAbs_EDGE;  break;
205   case TopOpeBRepDS_VERTEX : se = TopAbs_VERTEX;break;
206   default:
207     break ;
208   }
209   if(S.ShapeType() != se) {
210     if(myMapShapeStatus.IsBound(I))
211       myMapShapeStatus.UnBind(I);
212     myMapShapeStatus.Bind(I,TopOpeBRepDS_NOK);
213     return Standard_False;
214   }
215   if(!myMapShapeStatus.IsBound(I))
216     myMapShapeStatus.Bind(I,TopOpeBRepDS_OK);
217   return Standard_True;;
218 }
219
220 //=======================================================================
221 //function : ChkIntgSamDom
222 //purpose  : 
223 //=======================================================================
224
225 Standard_Boolean TopOpeBRepDS_Check::ChkIntgSamDom()
226 {
227   Standard_Boolean b = Standard_True, bb = Standard_False;
228   TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
229   Standard_Integer NbSh = myHDS->NbShapes(), i, Curr, Loc;
230   for(i = 1;i <= NbSh; i++) {
231     // Verifie que les Shapes de mySameDomaine existe bien dans la DS
232     const TopoDS_Shape& Sind = myHDS->Shape(i);
233     const TopTools_ListOfShape& losi = BDS.ShapeSameDomain(Sind);
234     if(!CheckShapes(losi)) {
235       b = Standard_False;
236     }
237     
238     // Verification de SameDomaineRef
239     Curr = BDS.SameDomainRef(i);
240     Loc = BDS.SameDomainRef(Curr);
241     if(Curr && (Curr != Loc)) {
242       b = Standard_False;
243     }
244     
245     if(Curr) {
246       // Verification du type des differents Shapes SameDomain
247       const TopoDS_Shape& Sref = myHDS->Shape(Curr);
248       if(Sind.ShapeType() != Sref.ShapeType()) {
249         b = Standard_False;
250       }
251
252       // Verifier que ShapeSameDomain(Sref) contient bien Sind
253       // sauf si Sind == Sref
254       if(i != Curr) {
255         const TopTools_ListOfShape& losr = BDS.ShapeSameDomain(Sref);
256         TopTools_ListIteratorOfListOfShape liolos;
257         liolos.Initialize(losr);
258         while (liolos.More() ) {
259           const TopoDS_Shape& Sh = liolos.Value();
260           Loc = myHDS->Shape(Sh);
261           if(Loc == i) {
262             bb = Standard_True;
263             break;
264           }
265           liolos.Next();
266         }
267         if(!bb) {
268           b = Standard_False;
269         }
270       }
271     }
272   }
273   return b;
274 }
275
276 //=======================================================================
277 //function : CheckShapes
278 //purpose  : 
279 //=======================================================================
280
281 Standard_Boolean TopOpeBRepDS_Check::CheckShapes
282 (const TopTools_ListOfShape& LS ) const
283 {
284   Standard_Integer index;
285   TopTools_ListIteratorOfListOfShape it(LS);
286   while (it.More()) {
287     const TopoDS_Shape& itS = it.Value();
288     index = myHDS->Shape(itS);
289     if (!index) return Standard_False;
290     it.Next();
291   }
292   return Standard_True;
293 }
294
295 //=======================================================================
296 //function : OneVertexOnPnt
297 //purpose  : 
298 //=======================================================================
299
300 Standard_Boolean TopOpeBRepDS_Check::OneVertexOnPnt(){
301   Standard_Boolean b = Standard_True;
302 //  Standard_Integer i, j, k;
303   Standard_Integer i, j;
304   Standard_Integer Curr1, Curr2, sdr1, sdr2;
305   Standard_Integer NbVe = 0, NbPo = myHDS->NbPoints();
306 //  Standard_Real tol, tol1, tol2, Dist;
307   Standard_Real tol1, tol2, Dist;
308   TColStd_IndexedMapOfInteger vert;
309   vert.Clear();
310   for(i = 1;i <= myHDS->NbShapes();i++) {
311     const TopoDS_Shape& S = myHDS->Shape(i);
312     if((S.ShapeType() == TopAbs_VERTEX) &&
313        myHDS->HasShape(S))
314       vert.Add(i);
315   }
316   NbVe = vert.Extent();
317   for(i = 1;i <= NbVe; i++) {
318     Curr1 = vert.FindKey(i);
319     const TopoDS_Shape& S1 = myHDS->Shape(Curr1);
320     sdr1 = myHDS->SameDomainReference(S1);
321     for(j = i+1;j <= NbVe; j++) {
322       Curr2 = vert.FindKey(j);
323       const TopoDS_Shape& S2 = myHDS->Shape(Curr2);
324       sdr2 = myHDS->SameDomainReference(S2);
325       tol1 = TopOpeBRepTool_ShapeTool::Tolerance(S1);
326       tol2 = TopOpeBRepTool_ShapeTool::Tolerance(S2);
327       const gp_Pnt& P1 = TopOpeBRepTool_ShapeTool::Pnt(S1);
328       const gp_Pnt& P2 = TopOpeBRepTool_ShapeTool::Pnt(S2);
329       Dist = P1.Distance(P2);
330       if(Dist <= tol1 + tol2) {
331         if(sdr1 != sdr2) {
332           b = Standard_False;
333         }
334       }
335       else if(sdr1 == sdr2) {
336         b = Standard_False;
337       }
338     }
339     TopOpeBRepDS_PointExplorer PE(myHDS->DS());
340     for(;PE.More(); PE.Next()) {
341       const TopOpeBRepDS_Point& dsPnt = PE.Point();
342       const gp_Pnt& Pnt1 = dsPnt.Point();
343       tol1 = dsPnt.Tolerance();
344       tol2 = TopOpeBRepTool_ShapeTool::Tolerance(S1);
345       const gp_Pnt& Pnt2 = TopOpeBRepTool_ShapeTool::Pnt(S1);
346       Dist = Pnt1.Distance(Pnt2);
347       if(Dist <= tol1 + tol2) {
348         b = Standard_False;
349       }
350     }
351   }
352   for(i = 1;i <= NbPo; i++) {
353     TopOpeBRepDS_PointExplorer PE(myHDS->DS());
354     if(PE.IsPoint(i)) {
355       const TopOpeBRepDS_Point& dsPnt1 = myHDS->Point(i);
356       for(j = i+1;j < NbPo;j++) {
357         const TopOpeBRepDS_Point& dsPnt2 = myHDS->Point(j);
358         if(dsPnt1.IsEqual(dsPnt2)) {
359         }
360       }
361     }
362   }
363   
364   return b;
365 }
366
367 //=======================================================================
368 //function : CheckEdgeParameter
369 //purpose  : 
370 //=======================================================================
371
372 ///Standard_Boolean TopOpeBRepDS_Check::CheckEdgeParameter() const
373 Standard_Boolean CheckEdgeParameter(const Handle(TopOpeBRepDS_HDataStructure)& myHDS)
374 {
375   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
376   const TopOpeBRepDS_DataStructure& DS = myHDS->DS();
377   Standard_Integer i,nshape = DS.NbShapes();
378   Standard_Boolean IsOK = Standard_True;
379   for (i = 1; i <= nshape; i++) {
380     // Integrity of Interferences : Check parameter of EdgeInterferences
381     const TopOpeBRepDS_ListOfInterference& LI = DS.ShapeInterferences(i);
382     it1.Initialize(LI);
383     while (it1.More() ) {
384       Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
385       Handle(TopOpeBRepDS_EdgeVertexInterference) EVI =
386         Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I1);
387       if(!EVI.IsNull()) {
388         Standard_Integer Param = (Standard_Integer ) EVI->Parameter();
389         if(Param > 1.e50) {
390           IsOK = Standard_False;
391         }
392       }
393       it1.Next();
394     }
395   }
396   
397   Standard_Integer ncurve = DS.NbCurves();
398   for (i = 1; i <= ncurve; i++) {
399     // Integrity of Interferences : Check parameter of CurvesInterferences
400     const TopOpeBRepDS_ListOfInterference& LI = DS.CurveInterferences(i);
401     it1.Initialize(LI);
402     while (it1.More() ) {
403       const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
404       Handle(TopOpeBRepDS_CurvePointInterference) CPI (Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I1));
405       if(!CPI.IsNull()) {
406         Standard_Integer Param = 
407           (Standard_Integer ) TopOpeBRepDS_InterferenceTool::Parameter(CPI);
408         if(Param > 1.e50) {
409           IsOK = Standard_False;
410         }
411       }
412       it1.Next();
413     }
414     
415   }
416   return IsOK;
417 }
418
419 //=======================================================================
420 //function : PrintIntg
421 //purpose  : 
422 //=======================================================================
423 Standard_OStream& TopOpeBRepDS_Check::PrintIntg(Standard_OStream& OS)
424 {
425   OS<<std::endl<<std::endl<<"************************************************"<<std::endl;
426   OS<<"state of the DS : (only the tested elements)"<<std::endl<<std::endl;
427   
428   //Display of the geometry
429   PrintMap(myMapSurfaceStatus, "Surface", OS);
430   PrintMap(myMapCurveStatus,   "Curve",   OS);
431   PrintMap(myMapPointStatus,   "Point",   OS);
432   
433   //display of the topology
434   TopOpeBRepDS_DataMapIteratorOfDataMapOfCheckStatus DMI(myMapShapeStatus);
435   TopOpeBRepDS_DataMapOfCheckStatus MapVertex, MapEdge, MapWire, MapFace, MapSolid;
436   Standard_Integer i;
437   // different Map keep their index of myMapShapeStatus
438   for(DMI.Reset();DMI.More();DMI.Next()) {
439     i = DMI.Key();
440     const TopoDS_Shape& S =myHDS->Shape(i);
441     switch(S.ShapeType()) {
442     case TopAbs_VERTEX: MapVertex.Bind(i, DMI.Value()); break;
443     case TopAbs_EDGE: MapEdge.Bind(i, DMI.Value()); break;
444     case TopAbs_WIRE: MapWire.Bind(i, DMI.Value()); break;
445     case TopAbs_FACE: MapFace.Bind(i, DMI.Value()); break;
446     case TopAbs_SOLID: MapSolid.Bind(i, DMI.Value()); break;
447     default:
448       break ;
449     }
450   }
451   
452   PrintMap(MapVertex, "Vertex", OS);
453   PrintMap(MapEdge, "Edge",   OS);
454   PrintMap(MapWire, "Wire",   OS);
455   PrintMap(MapFace, "Face",   OS);
456   PrintMap(MapSolid, "Solid",  OS);
457   
458   OS<<std::endl<<std::endl;
459   return OS;
460 }
461
462 //=======================================================================
463 //function : PrintMap
464 //purpose  : 
465 //=======================================================================
466
467 Standard_OStream& TopOpeBRepDS_Check::PrintMap(TopOpeBRepDS_DataMapOfCheckStatus& MapStat,
468                                                const Standard_CString eltstr,
469                                                Standard_OStream& OS)
470 {
471   TopOpeBRepDS_DataMapIteratorOfDataMapOfCheckStatus DMI(MapStat);
472   DMI.Initialize(MapStat);
473   if(DMI.More()) {
474     Standard_Boolean b = Standard_True;
475     OS<<" "<<eltstr<<"\t(/"<<MapStat.Extent()<<")\tnumber ";
476     
477     PrintElts(MapStat, TopOpeBRepDS_OK,  b, OS);
478     if(!b) OS<<" = OK"<<std::endl;
479     PrintElts(MapStat, TopOpeBRepDS_NOK, b, OS);
480     if(!b) OS<<" = NOK"<<std::endl;
481   }    
482   return OS;
483 }
484
485 //=======================================================================
486 //function : PrintElts
487 //purpose  : Print the elements in the state stat of MapStat
488 //=======================================================================
489 Standard_OStream& TopOpeBRepDS_Check::PrintElts(TopOpeBRepDS_DataMapOfCheckStatus& MapStat,
490                                                 const TopOpeBRepDS_CheckStatus Stat,
491                                                 Standard_Boolean& b,
492                                                 Standard_OStream& OS)
493 {
494   TopOpeBRepDS_DataMapIteratorOfDataMapOfCheckStatus DMI(MapStat);
495   Standard_Boolean bb = !b;
496   b = Standard_True;
497   Standard_Integer i;
498   TopOpeBRepDS_CheckStatus s;
499   for(DMI.Reset();DMI.More();DMI.Next()) {
500     s = DMI.Value();
501     i = DMI.Key();
502     if(s == Stat) {
503       if(b) b=!b; 
504       if(bb){OS<<"\t\tnumber ";bb=!bb;}
505       OS<<i<<" ";
506     }
507   }
508   return OS;
509 }
510
511 //=======================================================================
512 //function : Print
513 //purpose  : 
514 //=======================================================================
515 Standard_OStream& TopOpeBRepDS_Check::Print
516 (const TopOpeBRepDS_CheckStatus stat,
517  Standard_OStream& OS)
518 {
519   switch(stat) {
520   case TopOpeBRepDS_OK: OS<<"OK";break;
521   case TopOpeBRepDS_NOK: OS<<"NOK";break;
522   default : break;
523   }
524   return OS;
525 }
526
527 //=======================================================================
528 //function : PrintShape
529 //purpose  : 
530 //=======================================================================
531 Standard_OStream& TopOpeBRepDS_Check::PrintShape
532 (const TopAbs_ShapeEnum SE,
533  Standard_OStream& OS)
534 {
535   switch(SE) {
536   case TopAbs_SOLID   : OS<<"Solid ";   break;
537   case TopAbs_SHELL   : OS<<"Shell ";   break;
538   case TopAbs_FACE    : OS<<"Face  ";    break;
539   case TopAbs_WIRE    : OS<<"Wire  ";    break;
540   case TopAbs_EDGE    : OS<<"Edge  ";    break;
541   case TopAbs_VERTEX  : OS<<"Vertex";  break;
542   default:
543     break ;
544   }
545   return OS;
546 }
547
548 //=======================================================================
549 //function : PrintShape
550 //purpose  : 
551 //=======================================================================
552 Standard_OStream& TopOpeBRepDS_Check::PrintShape
553 (const Standard_Integer index,
554  Standard_OStream& OS)
555 {
556   if(myHDS->NbShapes() < index) { 
557     OS<<"**PB**IN**TopOpeBRepDS_Check::PrintShape** ";
558     return OS;
559   }
560   if(!myMapShapeStatus.IsBound(index)) {
561     OS<<"NO CHECK HAS PROCESSING"<<std::endl;
562     return OS;
563   }
564   OS<<" ";
565   myHDS->Shape(index);
566
567   return OS;
568 }
569
570 //=======================================================================
571 //function : HDS
572 //purpose  : 
573 //=======================================================================
574
575 const Handle(TopOpeBRepDS_HDataStructure)&  TopOpeBRepDS_Check::HDS()const 
576 {
577   return myHDS;
578 }
579
580
581 //=======================================================================
582 //function : ChangeHDS
583 //purpose  : 
584 //=======================================================================
585
586 Handle(TopOpeBRepDS_HDataStructure)&  TopOpeBRepDS_Check::ChangeHDS()
587 {
588   return myHDS;
589 }