b5ff0933af5bbb7a27b86c33b894b03dafaf4052
[occt.git] / src / BOPTest / BOPTest_TolerCommands.cxx
1 // Created on: 2000-03-16
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21
22 #include <BOPTest.ixx>
23 #include <stdio.h>
24 #include <TCollection_AsciiString.hxx>
25 #include <TColStd_IndexedMapOfTransient.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <DBRep.hxx>
29 #include <gp_Pnt2d.hxx>
30
31 #include <Geom_Curve.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom_Surface.hxx>
34
35 #include <TopoDS.hxx>
36 #include <TopoDS_Vertex.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Face.hxx>
39
40 #include <TopAbs_Orientation.hxx>
41
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
43 #include <TopTools_ListOfShape.hxx>
44 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
45 #include <TopTools_MapOfShape.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47
48 #include <BRep_TVertex.hxx>
49 #include <BRep_TEdge.hxx>
50 #include <BRep_ListOfCurveRepresentation.hxx>
51 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
52 #include <BRep_CurveRepresentation.hxx>
53 #include <BRep_Tool.hxx>
54 #include <BRep_Builder.hxx>
55 #include <BRep_TFace.hxx>
56
57 #include <TopLoc_Location.hxx>
58
59 #include <BRepLib.hxx>
60
61 #include <TopExp.hxx>
62 #include <TopExp_Explorer.hxx>
63
64 static 
65   Standard_Integer breducetolerance (Draw_Interpretor&, Standard_Integer, const char** );
66 static 
67   Standard_Integer  btolx           (Draw_Interpretor&, Standard_Integer, const char** );
68 static
69   Standard_Integer  bopaddpcs       (Draw_Interpretor&, Standard_Integer, const char** );
70 //
71 static 
72   void ProcessVertex(const TopoDS_Vertex&,
73                      const TopTools_ListOfShape&,
74                      const TopTools_ListOfShape&);
75 static
76   void ProcessEdge(const TopoDS_Edge&, const Standard_Real);
77
78 static
79   void ReduceVertexTolerance (const TopoDS_Shape&);
80
81 static 
82   void ReduceFaceTolerance (const TopoDS_Shape&);
83
84 static
85   void ReduceEdgeTolerance (const TopoDS_Shape&, const Standard_Real);
86
87
88 //=======================================================================
89 //function : TolerCommands
90 //purpose  : 
91 //=======================================================================
92   void  BOPTest::TolerCommands(Draw_Interpretor& theCommands)
93 {
94   static Standard_Boolean done = Standard_False;
95   if (done) 
96     return;
97
98   done = Standard_True;
99   // Chapter's name
100   const char* g = "CCR commands";
101   //
102   theCommands.Add("breducetolerance" ,  "Use >breducetolerance Shape [maxTol=0.01]",  __FILE__, breducetolerance, g);
103   theCommands.Add("btolx"     ,  "Use >btolx Shape [minTol=1.e-7]",  __FILE__, btolx, g);
104   theCommands.Add("bopaddpcs" ,  "Use >bopaddpcs Shape"           ,  __FILE__, bopaddpcs, g);
105 }
106
107 //=======================================================================
108 //function : btolx
109 //purpose  : 
110 //=======================================================================
111 Standard_Integer  btolx(Draw_Interpretor& di, Standard_Integer n,  const char** a)
112 {
113   if (n<2) {
114     di << " Use >btolx Shape [minTol=1.e-7]\n";
115     return 1;
116   }
117
118   TopoDS_Shape aS = DBRep::Get(a[1]);
119   
120   if (aS.IsNull()) {
121     di << " Null shape is not allowed \n";
122     return 1;
123   }
124   //
125   Standard_Real aTolEMin=1.e-7;
126   if (n==3) {
127     aTolEMin=atof(a[2]);
128   }
129   //
130   // Edge Tolerances
131   ReduceEdgeTolerance(aS, aTolEMin);
132   //
133   // Face Tolerances
134   ReduceFaceTolerance(aS);
135   //
136   // Vertex Tolerances
137   ReduceVertexTolerance(aS);
138   //
139   BRepLib::SameParameter(aS, 1.e-7, Standard_True);
140   //
141   DBRep::Set (a[1], aS);
142   return 0;
143 }
144 //=======================================================================
145 //function : ReduceEdgeTolerance
146 //purpose  : 
147 //=======================================================================
148 void ReduceEdgeTolerance (const TopoDS_Shape& aS, const Standard_Real aTolTreshold)
149 {
150   Standard_Integer i, aNbE;
151   TopTools_IndexedMapOfShape aEMap;
152   //
153   TopExp::MapShapes(aS, TopAbs_EDGE, aEMap);
154   //
155   aNbE=aEMap.Extent();
156   for (i=1; i<=aNbE; i++) {
157     const TopoDS_Edge& aE= TopoDS::Edge(aEMap(i));
158
159     ProcessEdge(aE, aTolTreshold);
160   } 
161 }
162 //=======================================================================
163 //function : ReduceFaceTolerance
164 //purpose  : 
165 //=======================================================================
166 void ReduceFaceTolerance (const TopoDS_Shape& aS)
167 {
168   Standard_Integer i, j, aNbF, aNbE;
169   Standard_Real aTolE, aTolx, aTolEMin;
170   TopTools_IndexedMapOfShape aFMap, aEMap;
171   //
172   aTolEMin=1.e-7;
173   //
174   TopExp::MapShapes(aS, TopAbs_FACE, aFMap);
175   aNbF=aFMap.Extent();
176   for (i=1; i<=aNbF; i++) {
177     aTolx=1.e6;
178     const TopoDS_Face& aF= TopoDS::Face(aFMap(i));
179     Handle(BRep_TFace)& aTF = *((Handle(BRep_TFace)*)&aF.TShape());
180     //
181     TopExp::MapShapes(aF, TopAbs_EDGE, aEMap);
182     aNbE=aEMap.Extent();
183     for (j=1; j<=aNbE; ++j) {
184       const TopoDS_Edge& aE= TopoDS::Edge(aEMap(j));
185       aTolE =BRep_Tool::Tolerance(aE);
186       if (aTolE<aTolx) {
187         aTolx=aTolE;
188       }
189     }
190     aTolE=(aTolx>aTolEMin) ? aTolx : aTolEMin;
191     aTF->Tolerance(aTolE);
192   }
193 }
194 //=======================================================================
195 //function : ReduceVertexTolerance
196 //purpose  : 
197 //=======================================================================
198 void ReduceVertexTolerance (const TopoDS_Shape& aS)
199 {
200   Standard_Integer i, aNbV;
201   TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap;
202
203   TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
204   TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
205
206   aNbV=aVEMap.Extent();
207   for (i=1; i<=aNbV; i++) {
208     const TopoDS_Vertex& aV= TopoDS::Vertex(aVEMap.FindKey(i));
209     const TopTools_ListOfShape& aLE=aVEMap(i);
210     const TopTools_ListOfShape& aLF=aVFMap.FindFromKey(aV);
211     
212     ProcessVertex(aV, aLE, aLF);
213   }
214 }
215 //=======================================================================
216 //function : ProcessEdge
217 //purpose  : 
218 //=======================================================================
219 void ProcessEdge(const TopoDS_Edge& aE, const Standard_Real aTolTreshold)
220 {
221   Standard_Integer i, aNb=23;
222   Standard_Real aTolE, aD2, aTolMax2, aT1, aT2, aT, dT;
223   gp_Pnt aPC3D, aP3D;
224   gp_Pnt2d aPC2D;
225
226   //TopTools_ListIteratorOfListOfShape anIt;// Wng in Gcc 3.0
227   BRep_ListIteratorOfListOfCurveRepresentation itcr;
228   //
229   Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aT1, aT2);
230   if (aC3D.IsNull()) {
231     return;
232   }
233   //
234   dT=(aT2-aT1)/aNb;
235   //
236   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
237   const TopLoc_Location& Eloc = aE.Location();
238   //
239   aTolMax2=-1.e6;
240   const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
241   //
242   itcr.Initialize(aLCR);
243   for (; itcr.More(); itcr.Next()) {
244     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
245     const TopLoc_Location& loc = cr->Location();
246     TopLoc_Location L = (Eloc * loc);//.Predivided(aV.Location());
247     //
248     // 3D-Curve
249     if (cr->IsCurve3D()) {
250       continue;
251     }
252     //
253     // 2D-Curve
254     else if (cr->IsCurveOnSurface()) {
255       const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
256       if (aC2D.IsNull()) {
257         continue;
258       }
259       // Surface
260       const Handle(Geom_Surface)& aS=cr->Surface();
261       //
262       // 2D-point treatment
263       for (i=0; i<=aNb; ++i) {
264         aT=aT1+i*dT;
265         if (i==aNb) {
266           aT=aT2;
267         }
268         aPC3D=aC3D->Value(aT);
269         aPC2D=aC2D->Value(aT);
270         aS->D0(aPC2D.X(), aPC2D.Y(), aP3D);
271         aP3D.Transform(L.Transformation());
272         aD2=aPC3D.SquareDistance(aP3D);
273         if (aD2 > aTolMax2) {
274           aTolMax2=aD2;
275         }
276       }
277     } //if (cr->IsCurveOnSurface())
278   }//for (; itcr.More(); itcr.Next())
279
280   //#########################################################
281   //
282   if (aTolMax2<0.){
283     return;
284   }
285   //
286   aTolE =BRep_Tool::Tolerance(aE);
287   //
288   aTolMax2=sqrt(aTolMax2); 
289   
290   //printf(" aTolMax=%15.10lf, aTolWas=%15.10lf\n", aTolMax2, aTolE);
291
292   Standard_Real aTolSet;
293   aTolSet=(aTolMax2>aTolTreshold) ? aTolMax2 : aTolTreshold;
294
295   TE->Tolerance(aTolSet);
296 }
297 //=======================================================================
298 //function : ProcessVertex
299 //purpose  : 
300 //=======================================================================
301 void ProcessVertex(const TopoDS_Vertex& aV,
302                    const TopTools_ListOfShape& aLE,
303                    const TopTools_ListOfShape& aLF)
304 {
305   Standard_Real aTol, aTol2, aD2, aTolMax2, aTolE, aParam;
306   gp_Pnt aPC3D;
307   gp_Pnt2d aPC2D;
308   TopAbs_Orientation anOrV;
309
310   TopTools_ListIteratorOfListOfShape anIt;
311   TopTools_MapOfShape aProcessedEdges;
312   TopExp_Explorer aVExp;
313   
314   BRep_ListIteratorOfListOfCurveRepresentation itcr;
315   //
316   aTolMax2=-1.e6;
317   //
318   Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape());
319   const gp_Pnt& aPV3D = TV->Pnt();
320   aTol =BRep_Tool::Tolerance(aV);
321   aTol2=aTol*aTol;
322   //
323   anIt.Initialize(aLE);
324   for (; anIt.More(); anIt.Next()) {
325     const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
326     //
327     if (aProcessedEdges.Contains(aE)) {
328       continue;
329     }
330     aProcessedEdges.Add(aE);                           
331     //
332     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
333     const TopLoc_Location& Eloc = aE.Location();
334     //
335     aVExp.Init(aE, TopAbs_VERTEX);
336     for (; aVExp.More(); aVExp.Next()) {
337       const TopoDS_Vertex& aVx=TopoDS::Vertex(aVExp.Current());
338       //
339       if (!aVx.IsSame(aV)) {
340         continue;
341       }
342       //
343       anOrV=aVx.Orientation();
344       if (!(anOrV==TopAbs_FORWARD || anOrV==TopAbs_REVERSED)) {
345         continue;
346       }
347       //
348       const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
349       itcr.Initialize(aLCR);
350       for (; itcr.More(); itcr.Next()) {
351         const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
352         const TopLoc_Location& loc = cr->Location();
353         TopLoc_Location L = (Eloc * loc).Predivided(aV.Location());
354         //
355         // 3D-Curve
356         if (cr->IsCurve3D()) {
357           const Handle(Geom_Curve)& aC3D = cr->Curve3D();
358           //
359           if (aC3D.IsNull()) {
360             continue;
361           }
362           // 3D-point treatment
363           aParam=BRep_Tool::Parameter(aVx, aE);
364           aPC3D= aC3D->Value(aParam);
365           aPC3D.Transform(L.Transformation());
366           aD2=aPV3D.SquareDistance(aPC3D);
367           if (aD2 > aTolMax2) {
368             aTolMax2=aD2;
369           }
370           //
371         }//if (cr->IsCurve3D())
372         //
373         // 2D-Curve
374         else if (cr->IsCurveOnSurface()) {
375           const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
376           if (aC2D.IsNull()) {
377             continue;
378           }
379           // Surface
380           const Handle(Geom_Surface)& aS=cr->Surface();
381           //
382           // 2D-point treatment
383           aParam=BRep_Tool::Parameter(aVx, aE, aS, L);
384           aPC2D=aC2D->Value(aParam);
385           aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D);
386           aPC3D.Transform(L.Transformation());
387           aD2=aPV3D.SquareDistance(aPC3D);
388           if (aD2 > aTolMax2) {
389             aTolMax2=aD2;
390           }
391         } //if (cr->IsCurveOnSurface())
392
393       }//for (; itcr.More(); itcr.Next())
394     }//for (; aVExp.More(); aVExp.Next()) 
395   }//for (; anIt.More(); anIt.Next()) 
396   //#########################################################
397   //
398   // Reducing
399   if (aTolMax2<0.){
400     return;
401   }
402   //
403   aTolMax2=sqrt(aTolMax2); 
404   if (aTolMax2>aTol) {
405     return;
406   }
407   //
408   aProcessedEdges.Clear();
409   anIt.Initialize(aLE);
410   for (; anIt.More(); anIt.Next()) {
411     const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
412
413     if (aProcessedEdges.Contains(aE)) {
414       continue;
415     }
416     aProcessedEdges.Add(aE);
417
418     aTolE =BRep_Tool::Tolerance(aE);
419     if (aTolMax2 < aTolE) {
420       aTolMax2=aTolE;
421     }
422   }
423   //
424   aProcessedEdges.Clear();
425   anIt.Initialize(aLF);
426   for (; anIt.More(); anIt.Next()) {
427     const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
428     
429     if (aProcessedEdges.Contains(aF)) {
430       continue;
431     }
432     aProcessedEdges.Add(aF);
433     
434     aTolE =BRep_Tool::Tolerance(aF);
435     if (aTolMax2 < aTolE) {
436       aTolMax2=aTolE;
437     }
438   }
439   //
440   if (aTolMax2>aTol) {
441     return;
442   }
443   //
444   // Update Tolerance
445   TV->Tolerance(aTolMax2);
446 }
447 //=======================================================================
448 //function : breducetolerance
449 //purpose  : 
450 //=======================================================================
451 Standard_Integer  breducetolerance(Draw_Interpretor& di, 
452                                    Standard_Integer n, 
453                                    const char** a)
454 {
455   if (n<2) {
456     di << " Use >bupdatetolerance Shape\n";
457     return 1;
458   }
459
460   TopoDS_Shape aS = DBRep::Get(a[1]);
461   
462   if (aS.IsNull()) {
463     di << " Null shape is not allowed \n";
464     return 1;
465   }
466   ReduceVertexTolerance(aS);
467   DBRep::Set (a[1], aS);
468   
469   return 0;
470 }
471 //
472 //
473 static
474   void PreparePCurves(const TopoDS_Shape& aShape, Draw_Interpretor& di);
475
476 //=======================================================================
477 //function : bopaddpcs
478 //purpose  : Some Edgesdo not contain P-Curveson Faces to which they belong to. 
479 //           These faces usually based on Geom_Plane surface.
480 //           To prevent sophisticated treatment the Command "bopaddpcs:
481 //           adds P-Curves for the edges . 
482 //=======================================================================
483 Standard_Integer  bopaddpcs(Draw_Interpretor& di, Standard_Integer n,  const char** a)
484 {
485   if (n<2) {
486     di << " Use >bopaddpcs Shape\n";
487     return 1;
488   }
489
490   TopoDS_Shape aS = DBRep::Get(a[1]);
491   
492   if (aS.IsNull()) {
493     di << " Null shape is not allowed \n";
494     return 1;
495   }
496   //
497   PreparePCurves(aS, di);
498   //
499   DBRep::Set (a[1], aS);
500   return 0;
501 }
502
503 //=======================================================================
504 //function : PreparePCurves
505 //purpose  : 
506 //=======================================================================
507 void PreparePCurves(const TopoDS_Shape& aShape, Draw_Interpretor& di)
508 {
509   Standard_Integer i, aNbE;
510   Standard_Real aTolE, aT1, aT2;
511   TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
512   TopLoc_Location aLoc;
513   Handle(Geom_Curve)   aC3D;
514   Handle(Geom2d_Curve) aC2D;
515   BRep_Builder aBB;
516   //
517   TopExp::MapShapesAndAncestors (aShape, TopAbs_EDGE, TopAbs_FACE, aEFMap);
518   //
519   aNbE=aEFMap.Extent();
520   for (i=1; i<=aNbE; ++i) {
521     const TopoDS_Edge& aE=TopoDS::Edge(aEFMap.FindKey(i));
522     //
523     if (BRep_Tool::Degenerated(aE)) {
524       continue;
525     }
526     //
527     aC3D=BRep_Tool::Curve(aE, aT1, aT2);
528     if (aC3D.IsNull()) {
529       continue;
530     }
531     aTolE=BRep_Tool::Tolerance(aE);
532     //
533     const TopTools_ListOfShape& aLF=aEFMap(i);
534     TopTools_ListIteratorOfListOfShape aFIt(aLF);
535     for (; aFIt.More(); aFIt.Next()) {
536       const TopoDS_Face& aF=TopoDS::Face(aFIt.Value());
537       //
538       // Map of surfaces on which the edge lays .
539       TColStd_IndexedMapOfTransient aSCRMap;
540       Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
541       const BRep_ListOfCurveRepresentation& aLCR=TE->Curves();
542       BRep_ListIteratorOfListOfCurveRepresentation itcr;
543       itcr.Initialize(aLCR);
544       for (; itcr.More(); itcr.Next()) {
545         const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
546         //
547         if (cr->IsCurveOnSurface()) {
548           const Handle(Geom_Surface)& aSCR=cr->Surface();
549           aSCRMap.Add(aSCR);
550         }
551         //
552       }
553       //
554       const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc);
555       if (!aSCRMap.Contains(aS)) {
556         // try to obtain 2D curve
557         aC2D=BRep_Tool::CurveOnSurface(aE, aS, aLoc, aT1, aT2);
558         if (aC2D.IsNull()) {
559           di << " Warning: Can not obtain P-Curve\n";
560           continue;
561         }
562         else {
563           aBB.UpdateEdge(aE, aC2D, aF, aTolE);
564         }
565       }
566     }
567   }
568 }