0023024: Update headers of OCCT files
[occt.git] / src / BOPTest / BOPTest_LowCommands.cxx
1 // Created on: 2001-03-28
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-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 #include <BOPTest.ixx>
22
23 #include <stdio.h>
24
25 #include <gp_Vec2d.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <gp_Pnt.hxx>
28
29 #include <Geom2d_Curve.hxx>
30 #include <Geom_Surface.hxx>
31
32 #include <BRep_Tool.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_GCurve.hxx>
35 #include <BRep_TEdge.hxx>
36 #include <BRep_CurveRepresentation.hxx>
37 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
38
39 #include <BRepClass3d_SolidClassifier.hxx>
40 #include <BRepClass_FaceClassifier.hxx>
41
42 #include <TopoDS.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopoDS_Iterator.hxx>
48
49 #include <TopTools_MapOfShape.hxx>
50
51 #include <TopLoc_Location.hxx>
52
53 #include <TopExp_Explorer.hxx>
54
55 #include <TopAbs.hxx>
56 #include <TopAbs_State.hxx>
57
58 #include <DBRep.hxx>
59
60 #include <DrawTrSurf.hxx>
61
62 #include <BOPTools_Tools2D.hxx>
63 #include <BOPTools_Tools3D.hxx>
64
65 #include <IntTools_Tools.hxx>
66
67 #include <BOP_Refiner.hxx>
68
69 #include <TCollection_AsciiString.hxx>
70 #include <IntTools_Context.hxx>
71 #include <IntTools_FClass2d.hxx>
72 #include <gp_Pnt2d.hxx>
73 #include <OSD_Chronometer.hxx>
74
75 #include <BRepTools.hxx>
76 #include <BOPTColStd_CArray1OfInteger.hxx>
77
78 static
79   Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
80                                       const TopoDS_Face& F,
81                                       Standard_Real& First,
82                                       Standard_Real& Last);
83 static
84   Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
85                                       const Handle(Geom_Surface)& S,
86                                       const TopLoc_Location& L,
87                                       Standard_Real& First,
88                                       Standard_Real& Last);
89 static
90   void PrintState (Draw_Interpretor& aDI,
91                    const TopAbs_State& aState);
92
93 //modified by NIZNHY-PKV Thu Nov 10 12:11:15 2011f
94 static
95   void DumpArray(const BOPTColStd_CArray1OfInteger& aC,
96                Draw_Interpretor& aDI);
97 //modified by NIZNHY-PKV Thu Nov 10 12:11:18 2011t
98
99 static  Standard_Integer bhaspc      (Draw_Interpretor& , Standard_Integer , const char** );
100 static  Standard_Integer baddve      (Draw_Interpretor& , Standard_Integer , const char** );
101 static  Standard_Integer bisclosed   (Draw_Interpretor& , Standard_Integer , const char** );
102 static  Standard_Integer bexplode    (Draw_Interpretor& , Standard_Integer , const char** );
103 static  Standard_Integer bupdateedge (Draw_Interpretor& , Standard_Integer , const char**);
104 static  Standard_Integer bremovesim  (Draw_Interpretor& , Standard_Integer , const char** );
105 static  Standard_Integer bopsetdisp  (Draw_Interpretor& , Standard_Integer , const char** );
106 static  Standard_Integer bfaceprepare(Draw_Interpretor& , Standard_Integer , const char** );
107 static  Standard_Integer brefine     (Draw_Interpretor& , Standard_Integer , const char** );
108 static  Standard_Integer bclassify   (Draw_Interpretor& , Standard_Integer , const char** );
109 static  Standard_Integer b2dclassify (Draw_Interpretor& , Standard_Integer , const char** );
110
111 static  Standard_Integer bhole       (Draw_Interpretor& , Standard_Integer , const char** );
112 static  Standard_Integer bxhole      (Draw_Interpretor& , Standard_Integer , const char** );
113 //=======================================================================
114 //function : LowCommands
115 //purpose  : 
116 //=======================================================================
117   void  BOPTest::LowCommands(Draw_Interpretor& theCommands)
118 {
119   static Standard_Boolean done = Standard_False;
120   if (done) return;
121   done = Standard_True;
122   // Chapter's name
123   const char* g = "CCR commands";
124   //
125   // Whether Edge has PCurve on Face
126   theCommands.Add("bhaspc"       , "Use >bhaspc Edge Face"    , __FILE__, bhaspc      , g);
127   theCommands.Add("baddve"       , "Use >addve  E V1 V2 p1 p2", __FILE__, baddve      , g);
128   theCommands.Add("bisclosed"    , "Use >bisclosed Edge Face" , __FILE__, bisclosed   , g);
129   theCommands.Add("bexplode"     , ""                         , __FILE__, bexplode    , g);
130   theCommands.Add("bupdateedge"  , "Use bupdateedge Edge Face", __FILE__, bupdateedge , g);
131   theCommands.Add("bremovesim"   , "Use bremovesim Face"      , __FILE__, bremovesim  , g);
132   theCommands.Add("bopsetdisp"   , "Use bopsetdisp"           , __FILE__, bopsetdisp  , g);
133   
134
135   theCommands.Add("bfaceprepare" , "Use bfaceprepare F1 "     , __FILE__, bfaceprepare, g);
136
137   theCommands.Add("brefine"      , "Use brefine Shape "       , __FILE__, brefine     , g);
138   theCommands.Add("bclassify"    , "Use >bclassify Solid Point [Tolerance=1.e-7]",
139                                                                 __FILE__, bclassify   , g);
140   theCommands.Add("b2dclassify"  , "Use >bclassify Face Point2d [Tol2D=Tol(Face)] ",
141                                                                 __FILE__, b2dclassify , g);
142   theCommands.Add("bhole"   , "Use bhole"                     , __FILE__, bhole       , g);
143   theCommands.Add("bxhole"  , "Use bxhole"                    , __FILE__, bxhole      , g);
144 }
145
146 //=======================================================================
147 //function : brefine
148 //purpose  : 
149 //=======================================================================
150 Standard_Integer  brefine (Draw_Interpretor& di,
151                            Standard_Integer n, 
152                            const char** a)
153 {
154   if (n<2) {
155     di << " Use >brefine Shape1\n";
156     return 1;
157   }
158
159   TopoDS_Shape aS = DBRep::Get(a[1]);
160  
161   
162   if (aS.IsNull()) {
163     di << " Null shape is not allowed \n";
164     return 1;
165   }
166
167   Standard_Boolean bIsDone;
168   BOP_Refiner aRefiner;
169   aRefiner.SetShape(aS);
170
171   aRefiner.Do();
172
173   bIsDone=aRefiner.IsDone();
174   
175   if (bIsDone) {
176     Standard_Integer aNbRemovedVertices, aNbRemovedEdges, iFlag=0;
177     aNbRemovedVertices=aRefiner.NbRemovedVertices();
178     aNbRemovedEdges=aRefiner.NbRemovedEdges();
179
180     if (aNbRemovedVertices) {
181       di << " Vertices removed=" << aNbRemovedVertices << "%d\n";
182       iFlag++;
183     }
184
185     if (aNbRemovedEdges) {
186       di << " Edges    removed=" << aNbRemovedEdges << "\n";
187       iFlag++;
188     }
189
190     // REFRESH
191     if (iFlag) {
192       TCollection_AsciiString aNm(a[1]);
193       Standard_CString pstr;
194       
195       pstr=aNm.ToCString();
196       DBRep::Set(pstr, aS);
197     }
198   }
199
200   else {
201     di << "Not Done, err=" << aRefiner.ErrorStatus() << "\n";
202   }
203   return 0;
204 }
205 //=======================================================================
206 //function : bfaceprepare
207 //purpose  : 
208 //=======================================================================
209 Standard_Integer  bfaceprepare(Draw_Interpretor& di, Standard_Integer n, const char** a)
210 {
211   if (n<2) {
212     di << " Use bfaceprepare> F1\n";
213     return 1;
214   }
215
216   TopoDS_Shape S1 = DBRep::Get(a[1]);
217  
218   
219   if (S1.IsNull()) {
220     di << " Null shape is not allowed \n";
221     return 1;
222   }
223   if (S1.ShapeType()!=TopAbs_FACE) {
224     di << " Type mismatch\n";
225     return 1;
226   }
227
228   const TopoDS_Face& aF1=TopoDS::Face(S1);
229
230   TopAbs_Orientation anOr;
231   anOr=aF1.Orientation();
232   if (anOr==TopAbs_FORWARD) {
233     return 0;
234   }
235   //
236   Standard_Real aTol;
237   TopoDS_Face newFace;
238   BRep_Builder aBB;
239   
240   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
241   Handle(Geom_Surface) aS=Handle(Geom_Surface)::DownCast(aS1->Copy());
242   aS->VReverse();
243
244   aTol=BRep_Tool::Tolerance(aF1);
245
246   aBB.MakeFace (newFace, aS, aTol);
247
248   TopExp_Explorer anExp(aF1, TopAbs_WIRE);
249   for (; anExp.More(); anExp.Next()) {
250     const TopoDS_Shape& newWire=anExp.Current();
251     aBB.Add(newFace, newWire);
252   }
253
254   TCollection_AsciiString aNm(a[1]), aNmNew("_r");
255   aNm=aNm+aNmNew;
256   Standard_CString an=aNm.ToCString();
257   di << an << "\n";
258   DBRep::Set(an, newFace); 
259   return 0;
260 }
261 //=======================================================================
262 //function : bopsetdisp
263 //purpose  : 
264 //=======================================================================
265 Standard_Integer bopsetdisp (Draw_Interpretor& di, Standard_Integer , const char** )
266 {
267   Standard_Integer aFlag;
268   
269   char* xr=getenv("MDISP");
270   if (xr==NULL) {
271     aFlag=putenv((char*)"MDISP=yes");
272     di << " MDISP=yes. Return code=" << aFlag << "\n";
273   }
274   else if (!strcmp (xr, "yes")) {
275     aFlag=putenv((char*)"MDISP=no");
276     di << " MDISP=no. Return code=" << aFlag << "\n";
277   }
278   else {
279     aFlag=putenv((char*)"MDISP=yes");
280     di << " MDISP=yes. Return code=" << aFlag << "\n";
281   }
282   
283
284   return 0;
285 }
286 //=======================================================================
287 //function : bremovesim
288 //purpose  : 
289 //=======================================================================
290 Standard_Integer bremovesim (Draw_Interpretor& di, Standard_Integer n, const char** a)
291 {
292   if (n<2) {
293     di << " Use bremovesim> Face\n";
294     return 1;
295   }
296
297   TopoDS_Shape S1 = DBRep::Get(a[1]);
298  
299   
300   if (S1.IsNull()) {
301     di << " Null shapes are not allowed \n";
302     return 1;
303   }
304   if (S1.ShapeType()!=TopAbs_FACE) {
305     di << " Type mismatch\n";
306     return 1;
307   }
308   
309
310   const TopoDS_Face& aF=TopoDS::Face(S1);
311   //
312   Handle(IntTools_Context) aCtx=new IntTools_Context;
313   BOPTools_Tools3D::RemoveSims (aF, aCtx);
314   //
315   di << " Ok\n";
316   return 0;
317 }
318 //=======================================================================
319 //function : bupdateedge
320 //purpose  : 
321 //=======================================================================
322 Standard_Integer bupdateedge (Draw_Interpretor& di, Standard_Integer n, const char** a)
323 {
324   if (n<3) {
325     di << " Use bupdateedge> Edge Face\n";
326     return 1;
327   }
328
329   TopoDS_Shape S1 = DBRep::Get(a[1]);
330   TopoDS_Shape S2 = DBRep::Get(a[2]);
331   
332   if (S1.IsNull() || S2.IsNull()) {
333     di << " Null shapes are not allowed \n";
334     return 1;
335   }
336   if (S1.ShapeType()!=TopAbs_EDGE || S2.ShapeType()!=TopAbs_FACE) {
337     di << " Type mismatch\n";
338     return 1;
339   }
340   
341   const TopoDS_Edge& aE=TopoDS::Edge(S1);
342   const TopoDS_Face& aF=TopoDS::Face(S2);
343   Handle(Geom2d_Curve) aC2D;
344
345   Standard_Real aTol;
346   aTol=BRep_Tool::Tolerance(aE);
347   BRep_Builder BB;
348   BB.UpdateEdge(aE, aC2D, aF, aTol);
349   di << " Ok\n";
350   return 0;
351 }
352
353 //=======================================================================
354 //function : bisclosed
355 //purpose  : 
356 //=======================================================================
357 Standard_Integer bisclosed (Draw_Interpretor& di, Standard_Integer n, const char** a)
358 {
359   if (n<3) {
360     di << " Use bisclosed> Edge Face\n";
361     return 1;
362   }
363
364   TopoDS_Shape S1 = DBRep::Get(a[1]);
365   TopoDS_Shape S2 = DBRep::Get(a[2]);
366   
367   if (S1.IsNull() || S2.IsNull()) {
368     di << " Null shapes are not allowed \n";
369     return 1;
370   }
371   if (S1.ShapeType()!=TopAbs_EDGE || S2.ShapeType()!=TopAbs_FACE) {
372     di << " Type mismatch\n";
373     return 1;
374   }
375   
376   const TopoDS_Edge& aE=TopoDS::Edge(S1);
377   const TopoDS_Face& aF=TopoDS::Face(S2);
378
379   Standard_Boolean anIsClosed;
380   anIsClosed=BRep_Tool::IsClosed(aE, aF); 
381
382   if (!anIsClosed) {
383     di << " Edge is not closed on this face\n";
384   }
385   else {
386     di << " Edge is closed on this face\n";
387   }
388   return 0;
389 }
390
391 //=======================================================================
392 //function : bhaspc
393 //purpose  : 
394 //=======================================================================
395 Standard_Integer bhaspc (Draw_Interpretor& di, Standard_Integer n, const char** a)
396 {
397   if (n<3) {
398     di << " Use bhaspc> Edge Face [do]\n";
399     return 1;
400   }
401
402   TopoDS_Shape S1 = DBRep::Get(a[1]);
403   TopoDS_Shape S2 = DBRep::Get(a[2]);
404   
405   if (S1.IsNull() || S2.IsNull()) {
406     di << " Null shapes are not allowed \n";
407     return 1;
408   }
409   if (S1.ShapeType()!=TopAbs_EDGE || S2.ShapeType()!=TopAbs_FACE) {
410     di << " Type mismatch\n";
411     return 1;
412   }
413
414   const TopoDS_Edge& aE=TopoDS::Edge(S1);
415   const TopoDS_Face& aF=TopoDS::Face(S2);
416   Standard_Real f2D, l2D; 
417
418   Handle(Geom2d_Curve) C2D=CurveOnSurface(aE, aF, f2D, l2D);
419   
420   if (C2D.IsNull()) {
421     di << " No 2D Curves detected\n";
422   }
423   else {
424     di << " Ok Edge has P-Curve on this Face\n";
425   }
426   
427   if (n==4) {
428     if (!strcmp(a[3], "do")) {
429       BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aF);  
430     }
431   }
432
433   return 0;
434 }
435   
436 //=======================================================================
437 //function : baddve
438 //purpose  : 
439 //=======================================================================
440 Standard_Integer baddve (Draw_Interpretor& di, Standard_Integer n, const char** a)
441 {
442   if (n<6) {
443     di << " Use baddve> E V1 V2 p1 p2\n";
444     return 1;
445   }
446
447   TopoDS_Shape S1 = DBRep::Get(a[1]);
448   TopoDS_Shape S2 = DBRep::Get(a[2]);
449   TopoDS_Shape S3 = DBRep::Get(a[3]);
450   if (S1.IsNull() || S2.IsNull() || S3.IsNull()) {
451     di << " Null shapes are not allowed \n";
452     return 1;
453   }
454
455   if (S1.ShapeType()!=TopAbs_EDGE || 
456       S2.ShapeType()!=TopAbs_VERTEX ||
457       S3.ShapeType()!=TopAbs_VERTEX ) {
458     di << " Type mismatch\n";
459     return 1;
460   }
461   const TopoDS_Edge& aE=TopoDS::Edge(S1);
462   const TopoDS_Vertex& aV1=TopoDS::Vertex(S2);
463   const TopoDS_Vertex& aV2=TopoDS::Vertex(S3);
464
465
466   Standard_Real p1, p2;
467   p1=atof(a[4]);
468   p2=atof(a[5]);
469   
470   TopoDS_Edge E=aE;
471   E.EmptyCopy();
472
473   BRep_Builder BB;
474   BB.Add  (E, aV1);
475   BB.Add  (E, aV2);
476   BB.Range(E, p1, p2);
477
478   DBRep::Set("ne", E);
479   return 0;
480 }
481
482 static Handle(Geom2d_Curve) nullPCurve;
483 //=======================================================================
484 //function : CurveOnSurface
485 //purpose  : 
486 //=======================================================================
487 Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
488                                     const TopoDS_Face& F,
489                                     Standard_Real& First,
490                                     Standard_Real& Last)
491 {
492   TopLoc_Location l;
493   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
494   TopoDS_Edge aLocalEdge = E;
495   if (F.Orientation() == TopAbs_REVERSED) {
496     aLocalEdge.Reverse();
497   }
498   return CurveOnSurface(aLocalEdge,S,l,First,Last);
499 }
500
501 //=======================================================================
502 //function : CurveOnSurface
503 //purpose  : 
504 //=======================================================================
505 Handle(Geom2d_Curve) CurveOnSurface(const TopoDS_Edge& E, 
506                                     const Handle(Geom_Surface)& S,
507                                     const TopLoc_Location& L,
508                                     Standard_Real& First,
509                                     Standard_Real& Last)
510 {
511   TopLoc_Location l = L.Predivided(E.Location());
512   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
513
514   // find the representation
515   BRep_ListIteratorOfListOfCurveRepresentation itcr
516     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
517
518   while (itcr.More()) {
519     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
520     if (cr->IsCurveOnSurface(S,l)) {
521       const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
522       GC->Range(First,Last);
523       if (GC->IsCurveOnClosedSurface() && Eisreversed)
524         return GC->PCurve2();
525       else
526         return GC->PCurve();
527     }
528     itcr.Next();
529   }
530   return nullPCurve;
531 }
532
533 //=======================================================================
534 //function : bexplode
535 //purpose  : 
536 //=======================================================================
537 static Standard_Integer bexplode(Draw_Interpretor& di,
538                                  Standard_Integer n, 
539                                  const char** a)
540 {
541   if (n <= 1) return 1;
542   TopoDS_Shape S = DBRep::Get(a[1]);
543   if (S.IsNull()) return 0;
544   char newname[1024];
545   strcpy(newname,a[1]);
546   char* p = newname;
547   while (*p != '\0') p++;
548   *p = '_';
549   p++;
550   Standard_Integer i = 0;
551   if (n == 2) {
552     TopoDS_Iterator itr(S);
553     while (itr.More()) {
554       i++;
555       sprintf(p,"%d",i);
556       DBRep::Set(newname,itr.Value());
557       di.AppendElement(newname);
558       itr.Next();
559     }
560   }
561   else {
562     // explode a type
563     TopAbs_ShapeEnum typ;
564     switch (a[2][0]) {
565       
566     case 'C' :
567     case 'c' :
568       if ((a[2][1] == 'd')||(a[2][1] == 'D')) 
569         typ = TopAbs_COMPOUND;
570       else
571         typ = TopAbs_COMPSOLID;
572       break;
573       
574     case 'S' :
575     case 's' :
576       if ((a[2][1] == 'O')||(a[2][1] == 'o')) 
577         typ = TopAbs_SOLID;
578       else if ((a[2][1] == 'H')||(a[2][1] == 'h')) 
579         typ = TopAbs_SHELL;
580       else
581         return 1;
582       break;
583       
584     case 'F' :
585     case 'f' :
586       typ = TopAbs_FACE;
587       break;
588       
589     case 'W' :
590     case 'w' :
591       typ = TopAbs_WIRE;
592       break;
593       
594     case 'E' :
595     case 'e' :
596       typ = TopAbs_EDGE;
597       break;
598       
599     case 'V' :
600     case 'v' :
601       typ = TopAbs_VERTEX;
602       break;
603       
604       default :
605         return 1;
606     }
607     
608     
609     TopExp_Explorer ex(S,typ);
610     for (; ex.More(); ex.Next()) {
611       const TopoDS_Shape& aS = ex.Current();
612       i++;
613       sprintf(p,"%d",i);
614       DBRep::Set(newname,aS);
615       di.AppendElement(newname);
616     }
617   }
618   return 0;
619 }
620
621 //=======================================================================
622 //function : bclassify
623 //purpose  : 
624 //=======================================================================
625 Standard_Integer bclassify (Draw_Interpretor& aDI,
626                             Standard_Integer n, 
627                             const char** a)
628 {
629   char sbf[512];        
630   
631   if (n < 3) {
632     sprintf(sbf, " Use >bclassify Solid Point [Tolerance=1.e-7]\n");
633     aDI<<sbf;
634     return 1;
635   }
636   
637   TopoDS_Shape aS = DBRep::Get(a[1]);
638   if (aS.IsNull()) {
639     sprintf(sbf, " Null Shape is not allowed here\n");
640     aDI<<sbf;
641     return 1;
642   }
643   
644   if (aS.ShapeType()!=TopAbs_SOLID) {
645     sprintf(sbf, " Shape type must be SOLID\n");
646     aDI<<sbf;
647     return 1;
648   }
649   //
650   Standard_Real aTol=1.e-7;
651   TopAbs_State aState = TopAbs_UNKNOWN;
652   gp_Pnt aP(8., 9., 10.);
653   
654   DrawTrSurf::GetPoint(a[2], aP);
655   
656   aTol=1.e-7; 
657   if (n==4) {
658     aTol=atof(a[3]);
659   }
660   //
661   BRepClass3d_SolidClassifier aSC(aS);
662   aSC.Perform(aP,aTol);
663   //
664   aState = aSC.State();
665   //
666   PrintState (aDI, aState);
667   //
668   return 0;
669 }
670 //
671 //=======================================================================
672 //function : b2dclassify
673 //purpose  : 
674 //=======================================================================
675 Standard_Integer b2dclassify (Draw_Interpretor& aDI,
676                               Standard_Integer n, 
677                               const char** a)
678 {
679   char sbf[512];        
680   
681   if (n < 3) {
682     sprintf(sbf, " Use >bclassify Face Point2d [Tol2D=Tol(Face)]\n");
683     aDI<<sbf;
684     return 1;
685   }
686   
687   TopoDS_Shape aS = DBRep::Get(a[1]);
688   if (aS.IsNull()) {
689     sprintf(sbf, " Null Shape is not allowed here\n");
690     aDI<<sbf;
691     return 1;
692   }
693   
694   if (aS.ShapeType()!=TopAbs_FACE) {
695     sprintf(sbf, " Shape type must be FACE\n");
696     aDI<<sbf;
697     return 1;
698   }
699   //
700   Standard_Real aTol;
701   TopAbs_State aState = TopAbs_UNKNOWN;
702   gp_Pnt2d aP(8., 9.);
703   
704   DrawTrSurf::GetPoint2d(a[2], aP);
705   
706   const TopoDS_Face& aF=TopoDS::Face(aS);
707   aTol=BRep_Tool::Tolerance(aF); 
708   if (n==4) {
709     aTol=atof(a[3]);
710   }
711   //
712   BRepClass_FaceClassifier aClassifier;
713   aClassifier.Perform(aF, aP, aTol);
714   //
715   aState = aClassifier.State();
716   //
717   PrintState (aDI, aState);
718   //
719   return 0;
720 }
721 //=======================================================================
722 //function : PrintState
723 //purpose  : 
724 //=======================================================================
725 void PrintState (Draw_Interpretor& aDI,
726                  const TopAbs_State& aState)
727 {
728   char sbf[512];        
729   TCollection_AsciiString sIN("IN"), sOUT("OUT of"), sON("ON"), sUNKNOWN("UNKNOWN"); 
730   //
731   sprintf(sbf, "The point is "); aDI<<sbf;
732   //
733   switch (aState) {
734   case TopAbs_IN:               
735     sprintf(sbf, sIN.ToCString());
736     break;
737   case TopAbs_OUT:              
738     sprintf(sbf, sOUT.ToCString());
739     break;
740   case TopAbs_ON:               
741     sprintf(sbf, sON.ToCString());
742     break;
743   case TopAbs_UNKNOWN:          
744     sprintf(sbf, sUNKNOWN.ToCString());
745     break;
746   default:
747     sprintf(sbf, sUNKNOWN.ToCString()); 
748     break;
749   }
750   aDI<<sbf; 
751         //
752   sprintf(sbf, " shape\n");
753   aDI<<sbf;
754   
755 }
756 //
757 //=======================================================================
758 //function : bhole
759 //purpose  : 
760 //=======================================================================
761 Standard_Integer bhole (Draw_Interpretor& aDI,
762                         Standard_Integer n, 
763                         const char** a)
764 {
765   char sbf[512];        
766   
767   if (n!=2) {
768     sprintf(sbf, " Use bhole Face\n");
769     aDI<<sbf;
770     return 1;
771   }
772   
773   TopoDS_Shape aS = DBRep::Get(a[1]);
774   if (aS.IsNull()) {
775     sprintf(sbf, " Null Shape is not allowed here\n");
776     aDI<<sbf;
777     return 1;
778   }
779   
780   if (aS.ShapeType()!=TopAbs_FACE) {
781     sprintf(sbf, " Shape type must be FACE\n");
782     aDI<<sbf;
783     return 1;
784   }
785   //
786   Standard_Boolean bIsHole;
787   Standard_Real aTol=1.e-7;
788   IntTools_FClass2d aFClass2d;
789   //
790   const TopoDS_Face& aF=TopoDS::Face(aS);
791   aTol=BRep_Tool::Tolerance(aF); 
792   //
793   aFClass2d.Init(aF, aTol);
794   //
795   bIsHole=aFClass2d.IsHole();
796   printf(" bIsHole=%d\n", bIsHole);
797   //
798   return 0;
799 }
800 //
801
802
803 //
804 //=======================================================================
805 //class : X_Chr
806 //purpose  : 
807 //=======================================================================
808 class X_Chr {
809  public:
810 //  X_Chr::X_Chr() {
811   X_Chr() {
812     Reset();
813   }
814   void Reset() {
815     myTime=0.;
816     myCnt=0;
817   }
818   void Start() {
819     myChronometer.Reset();
820     myChronometer.Start();
821   }
822   void Stop() {
823     Standard_Real aTime;
824     //
825     myChronometer.Stop();
826     myChronometer.Show(aTime);
827     myTime=myTime+aTime;
828     ++myCnt;
829   }
830   void Show(const char *pComment) {
831     printf("  Tps: %7.2lf\tCnt: %d\tfor %s\n", myTime, myCnt, pComment);
832   }
833   
834  protected:
835   Standard_Real myTime;
836   Standard_Integer myCnt;
837   OSD_Chronometer myChronometer;
838   
839 };
840
841 //
842 //=======================================================================
843 //function : bxhole
844 //purpose  : 
845 //=======================================================================
846 Standard_Integer bxhole (Draw_Interpretor& aDI,
847                          Standard_Integer n, 
848                          const char** a)
849 {
850   char sbf[512];        
851   Standard_Integer aNbIter;
852   //
853   if (n!=3) {
854     sprintf(sbf, " Use bxhole Face NbIter\n");
855     aDI<<sbf;
856     return 1;
857   }
858   
859   TopoDS_Shape aS = DBRep::Get(a[1]);
860   if (aS.IsNull()) {
861     sprintf(sbf, " Null Shape is not allowed here\n");
862     aDI<<sbf;
863     return 1;
864   }
865   if (aS.ShapeType()!=TopAbs_FACE) {
866     sprintf(sbf, " Shape type must be FACE\n");
867     aDI<<sbf;
868     return 1;
869   }
870   //
871   aNbIter=atoi(a[2]);
872   if (aNbIter<1) {
873     aNbIter=1;
874   }
875   //
876   Standard_Integer i;
877   Standard_Boolean bIsHole;
878   Standard_Real aTol, aUMin, aUMax, aVMin, aVMax;
879   gp_Pnt2d aP2DInf;
880   TopAbs_State aState;
881   X_Chr aChr;
882   //
883   aTol=1.e-7;
884   const TopoDS_Face& aF=TopoDS::Face(aS);
885   aTol=BRep_Tool::Tolerance(aF); 
886   //
887   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
888   aP2DInf.SetCoord(aUMin, aVMin);
889   //
890   // 1. New
891   aChr.Reset();
892   aChr.Start();
893   for (i=1; i<=aNbIter; ++i) {
894     IntTools_FClass2d aFClass2d;
895     //
896     aFClass2d.Init(aF, aTol);
897     //
898     bIsHole=aFClass2d.IsHole();
899   }
900   aChr.Stop();
901   aChr.Show(" new");
902   printf(" new bIsHole=%d\n", bIsHole);
903   //``````````````````````````````````````````
904   aChr.Reset();
905   aChr.Start();
906   for (i=1; i<=aNbIter; ++i) {
907     IntTools_FClass2d aFClass2d;
908     //
909     aFClass2d.Init(aF, aTol);
910     //
911     aState=aFClass2d.Perform(aP2DInf);
912     bIsHole=(aState==TopAbs_IN);
913   }
914   aChr.Stop();
915   aChr.Show(" was");
916   printf(" was bIsHole=%d\n", bIsHole);
917   //
918   return 0;
919 }