0f34565aa2620ae37beda8bde51e9b9501c1e22e
[occt.git] / src / BRepTest / BRepTest_CheckCommands.cxx
1 // Created on: 1996-02-23
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-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 #include <BRepTest.hxx>
18 #include <BRepAlgo.hxx>
19 #include <BRepCheck_Analyzer.hxx>
20 #include <BRepCheck_Result.hxx>
21 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
22 #include <TopoDS_Iterator.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopTools_DataMapOfShapeListOfShape.hxx>
25 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
26 #include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx>
27 #include <TopTools_ListOfShape.hxx>
28 #include <TopTools_ListIteratorOfListOfShape.hxx>
29 #include <DBRep_DrawableShape.hxx>
30 #include <Draw_SequenceOfDrawable3D.hxx>
31 #include <BRepCheck.hxx>
32 #include <BRepCheck_Edge.hxx>
33 #include <Draw_Interpretor.hxx>
34 #include <Draw_Appli.hxx>
35 #include <Draw.hxx>
36 #include <DBRep.hxx>
37 #include <BRepTest.hxx>
38 #include <GeometryTest.hxx>
39 #include <Precision.hxx>
40 #include <LocalAnalysis.hxx>
41 #include <LocalAnalysis_SurfaceContinuity.hxx>
42 #include <Geom_SphericalSurface.hxx>
43 #include <Geom_Surface.hxx>
44 #include <Geom_Curve.hxx>
45 #include <Geom2d_TrimmedCurve.hxx>
46 #include <Geom2d_Curve.hxx>
47 #include <DrawTrSurf.hxx>
48 #include <GeomAbs_Shape.hxx>
49 #include <TCollection_AsciiString.hxx>
50 #include <TopoDS.hxx>
51 #include <TopExp.hxx>
52 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
53 #include <TopTools_MapOfShape.hxx>
54 #include <TopTools_MapIteratorOfMapOfShape.hxx>
55 #include <TopoDS_Shape.hxx>
56 #include <TopoDS_Edge.hxx>
57 #include <TopoDS_Face.hxx>
58 #include <BRep_Tool.hxx>
59
60 #include <TopOpeBRepTool_PurgeInternalEdges.hxx>
61 //#include <TopOpeBRepTool_FuseEdges.hxx>
62 #include <BRepLib.hxx>
63 #include <BRepLib_FuseEdges.hxx>
64
65 #include <TopTools_HSequenceOfShape.hxx>
66 #include <BRep_Builder.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TColStd_HArray1OfInteger.hxx>
69
70 #include <Standard_ErrorHandler.hxx>
71 #include <Standard_Failure.hxx>
72
73 #include <stdio.h>
74
75 //Number of BRepCheck_Statuses in BRepCheck_Status.hxx file
76 //(BRepCheck_NoError is not considered, i.e. general status 
77 //is smaller by one specified in file)
78 static const Standard_Integer NumberOfStatus = 36;
79
80 static char* checkfaultyname = NULL;
81 Standard_EXPORT void BRepTest_CheckCommands_SetFaultyName(const char* name)
82 {
83   if (checkfaultyname != NULL) {
84     free(checkfaultyname);
85     checkfaultyname = NULL;
86   }
87   if (name == NULL) {
88     checkfaultyname = (char*)malloc(strlen("faulty_")+1);
89     strcpy(checkfaultyname,"faulty_");
90   }
91   else {
92     checkfaultyname = (char*)malloc(strlen(name)+1);
93     strcpy(checkfaultyname,name);
94   }
95 }
96
97
98 static TopTools_DataMapOfShapeListOfShape theMap;
99 static Standard_Integer nbfaulty = 0;
100 static Draw_SequenceOfDrawable3D lfaulty;
101
102 Standard_IMPORT Standard_Integer BRepCheck_Trace(const Standard_Integer phase);
103
104 //=======================================================================
105 //function : FindNamed
106 //=======================================================================
107 static Standard_Boolean FindNamed(const TopoDS_Shape& S,
108                                   char*& Name)
109 {
110   for (Standard_Integer i = 1 ;i <= lfaulty.Length(); i++) {
111     Handle(DBRep_DrawableShape) DS = 
112       Handle(DBRep_DrawableShape)::DownCast(lfaulty(i));
113     if (DS->Shape().IsSame(S)) {
114       Name = (char*)DS->Name();
115       return Standard_True;
116     }
117   }
118   return Standard_False;
119 }
120
121
122 //=======================================================================
123 //function : Contains
124 //=======================================================================
125 static Standard_Boolean Contains(const TopTools_ListOfShape& L,
126                                  const TopoDS_Shape& S)
127 {
128   TopTools_ListIteratorOfListOfShape it;
129   for (it.Initialize(L); it.More(); it.Next()) {
130     if (it.Value().IsSame(S)) {
131       return Standard_True;
132     }
133   }
134   return Standard_False;
135 }
136
137
138
139 //=======================================================================
140 //function : PrintSub
141 //=======================================================================
142 static void PrintSub(Standard_OStream& OS,
143                      const BRepCheck_Analyzer& Ana,
144                      const TopoDS_Shape& S,
145                      const TopAbs_ShapeEnum Subtype)
146      
147 {
148   char* Name;
149   BRepCheck_ListIteratorOfListOfStatus itl;
150   TopExp_Explorer exp;
151   for (exp.Init(S,Subtype); exp.More(); exp.Next()) {
152     const Handle(BRepCheck_Result)& res = Ana.Result(exp.Current());
153     const TopoDS_Shape& sub = exp.Current();
154     for (res->InitContextIterator();
155          res->MoreShapeInContext(); 
156          res->NextShapeInContext()) {
157       if (res->ContextualShape().IsSame(S) && 
158           !Contains(theMap(sub),S)) {
159         theMap(sub).Append(S);
160         itl.Initialize(res->StatusOnShape());
161         if (itl.Value() != BRepCheck_NoError) {
162           if (!FindNamed(sub,Name)) {
163             nbfaulty++;
164             Name = (char*)malloc(18*sizeof(char));
165             Sprintf(Name,"%s%d",checkfaultyname,nbfaulty);
166             DBRep::Set(Name,sub);
167             lfaulty.Append(Draw::Get((Standard_CString&)Name));
168           }
169           OS << "Shape " << Name << " ";
170           if (!FindNamed(S,Name)) {
171             nbfaulty++;
172             Name = (char*)malloc(18*sizeof(char));
173             Sprintf(Name,"%s%d",checkfaultyname,nbfaulty);
174             DBRep::Set(Name,S);
175             lfaulty.Append(Draw::Get((Standard_CString&)Name));
176           }
177           OS << " on shape " << Name << " :\n";
178           for (;itl.More(); itl.Next()) {
179             BRepCheck::Print(itl.Value(),OS);
180           }
181         }
182         break;
183       }
184     }
185   }
186 }
187
188
189 //=======================================================================
190 //function : Print
191 //=======================================================================
192 static void Print(Standard_OStream& OS,
193                   const BRepCheck_Analyzer& Ana,
194                   const TopoDS_Shape& S)
195 {
196   for (TopoDS_Iterator iter(S); iter.More(); iter.Next()) {
197     Print(OS,Ana,iter.Value());
198   }
199
200   char* Name;
201   TopAbs_ShapeEnum styp = S.ShapeType();
202   BRepCheck_ListIteratorOfListOfStatus itl;
203   if (!Ana.Result(S).IsNull() && !theMap.IsBound(S)) {
204     itl.Initialize(Ana.Result(S)->Status());
205     if (itl.Value() != BRepCheck_NoError) {
206       if (!FindNamed(S,Name)) {
207         nbfaulty++;
208         Name = (char*)malloc(18*sizeof(char));
209         Sprintf(Name,"%s%d",checkfaultyname,nbfaulty);
210         DBRep::Set(Name,S);
211         lfaulty.Append(Draw::Get((Standard_CString&)Name));
212       }
213       OS << "On Shape " << Name << " :\n";
214         
215       for (;itl.More(); itl.Next()) {
216         if (itl.Value() != BRepCheck_NoError)
217         BRepCheck::Print(itl.Value(),OS);
218       }
219     }
220   }
221   if (!theMap.IsBound(S)) {
222     TopTools_ListOfShape thelist;
223     theMap.Bind(S, thelist);
224   }
225
226   switch (styp) {
227   case TopAbs_EDGE:
228     PrintSub(OS,Ana,S,TopAbs_VERTEX);
229     break;
230   case TopAbs_WIRE:
231     PrintSub(OS,Ana,S,TopAbs_EDGE);
232     PrintSub(OS,Ana,S,TopAbs_VERTEX);
233     break;
234   case TopAbs_FACE:
235     PrintSub(OS,Ana,S,TopAbs_WIRE);
236     PrintSub(OS,Ana,S,TopAbs_EDGE);
237     PrintSub(OS,Ana,S,TopAbs_VERTEX);
238     break;
239   case TopAbs_SHELL:
240 //    PrintSub(OS,Ana,S,TopAbs_FACE);
241     break;
242   case TopAbs_SOLID:
243 //    PrintSub(OS,Ana,S,TopAbs_EDGE);
244     PrintSub(OS,Ana,S,TopAbs_SHELL);
245     break;
246   default:
247     break;
248   }
249
250 }
251
252 //=======================================================================
253 //function : computetolerance
254 //purpose  : 
255 //=======================================================================
256 static Standard_Integer computetolerance(Draw_Interpretor& di,
257                                          Standard_Integer narg, const char** a)
258 {
259   if (narg < 2) {
260     //std::cout << "Usage: computetolerance shape" << std::endl;
261     di << "Usage: computetolerance shape\n";
262     return 1;
263   }
264   TopoDS_Shape S = DBRep::Get(a[1]);
265   Standard_Real tol;
266   if (S.ShapeType() == TopAbs_EDGE) {
267     BRepCheck_Edge bce(TopoDS::Edge(S));
268     tol=bce.Tolerance();
269     //std::cout<< "Tolerance de " << (void*) &(*S.TShape()) << " : " << tol << std::endl;
270     Standard_SStream aSStream1;
271     aSStream1<< "Tolerance de " << (void*) &(*S.TShape()) << " : " << tol << "\n";
272     di << aSStream1;
273   }
274   else {
275     TopTools_MapOfShape theEdges;
276     TopExp_Explorer exp;
277     for (exp.Init(S, TopAbs_EDGE); exp.More(); exp.Next()) {
278       if (theEdges.Add(exp.Current())) {
279         BRepCheck_Edge bce(TopoDS::Edge(exp.Current()));
280         tol=bce.Tolerance();
281         //std::cout<< "Tolerance de " << (void*) &(*exp.Current().TShape()) << " : " << tol << "\n";
282         Standard_SStream aSStream2;
283         aSStream2<< "Tolerance de " << (void*) &(*exp.Current().TShape()) << " : " << tol << "\n";
284         di << aSStream2;
285       }
286     }
287     //std::cout << std::endl;
288     di << "\n";
289   }
290   return 0;
291 }
292
293 //=======================================================================
294 //function : checksection
295 //purpose  : Checks the closure of a section line
296 //=======================================================================
297 static Standard_Integer checksection(Draw_Interpretor& di,
298                                      Standard_Integer narg, const char** a)
299 {
300   if (narg < 2) {
301     di << a[0] << " shape [-r <ref_val>]\n";
302     return 1;
303   }
304
305   Standard_Integer aCompareValue = -1;
306   TopoDS_Shape S = DBRep::Get(a[1]);
307
308   for (Standard_Integer anAI = 2; anAI < narg; anAI++)
309   {
310     if (!strcmp(a[anAI], "-r"))
311     {
312       aCompareValue = Draw::Atoi(a[++anAI]);
313     }
314     else
315     {
316       di << "Error: Wrong option" << a[anAI] << "\n";
317     }
318   }
319
320   TopTools_MapOfShape theVertices;
321   TopExp_Explorer exp;
322   for (exp.Init(S, TopAbs_VERTEX); exp.More(); exp.Next()) {
323     if (!theVertices.Add(exp.Current())) 
324       theVertices.Remove(exp.Current());
325   }
326   //std::cout << " nb alone Vertices : " << theVertices.Extent() << std::endl;
327   di << " nb alone Vertices : " << theVertices.Extent() << "\n";
328
329   if (aCompareValue >= 0)
330   {
331     if (theVertices.Extent() == aCompareValue)
332     {
333       di << "Section is OK\n";
334     }
335     else
336     {
337       di << "Error: "<< aCompareValue << " vertices are expected but " <<
338                         theVertices.Extent() << " are found.\n";
339     }
340   }
341
342   char Name[32];
343   Standard_Integer ipp=0;
344   TopTools_MapIteratorOfMapOfShape itvx;
345   for (itvx.Initialize(theVertices); itvx.More(); itvx.Next()) {
346     ipp++;
347     Sprintf(Name,"alone_%d",ipp);
348     DBRep::Set(Name, itvx.Key());
349     //std::cout << Name << " " ;
350     di << Name << " " ;
351   }
352   //std::cout << std::endl;
353   di << "\n";
354   return 0;
355 }
356 //=======================================================================
357
358 //=======================================================================
359 //function : checkdiff
360 //purpose  : Checks the differences beetween a result and his arguments
361 //=======================================================================
362 static Standard_Integer checkdiff(Draw_Interpretor& di,
363                                   Standard_Integer narg, const char** a)
364 {
365   const char* syntaxe = "checkdiff arg1 [arg2..argn] result [closedSolid (0/1)] [geomCtrl (1/0)]";
366   if (narg < 3) {
367     if (narg==2) {
368       Standard_Integer bcrtrace=Draw::Atoi(a[narg-1]);
369       bcrtrace=BRepCheck_Trace(bcrtrace);
370       //std::cout << "BRepCheck_Trace : " << bcrtrace << std::endl;
371       di << "BRepCheck_Trace : " << bcrtrace << "\n";
372       //std::cout << syntaxe << std::endl;
373       di << syntaxe << "\n";
374       return 0;
375     }
376     //std::cout << syntaxe << std::endl;
377     di << syntaxe << "\n";
378     return 1;
379   }
380
381   Standard_Integer lastArg=narg-2;
382   Standard_Boolean closedSolid = Standard_False;
383   Standard_Boolean geomCtrl = Standard_True;
384   TopoDS_Shape resu = DBRep::Get(a[narg-1]);
385   if (resu.IsNull()) {
386     if (narg < 4) {
387       //std::cout << syntaxe << std::endl;
388       di << syntaxe << "\n";
389       return 1;
390     }
391     closedSolid = Draw::Atoi(a[narg-1]) != 0;
392     resu = DBRep::Get(a[narg-2]);
393     lastArg=narg-3;
394     if (resu.IsNull()) {
395       if (narg < 5) {
396         //std::cout << syntaxe << std::endl;
397         di << syntaxe << "\n";
398         return 1;
399       }
400       geomCtrl=closedSolid;
401       closedSolid = Draw::Atoi(a[narg-2]) != 0;
402       resu = DBRep::Get(a[narg-3]);
403       lastArg=narg-4;
404       if (resu.IsNull()) {
405         //std::cout << syntaxe << std::endl;
406         di << syntaxe << "\n";
407         return 1;
408       }
409     }
410   }
411   
412   TopTools_ListOfShape lesArgs;
413   for (Standard_Integer id=1; id <=lastArg; id++) {
414     lesArgs.Append(DBRep::Get(a[id]));
415   }
416
417   if (BRepAlgo::IsValid(lesArgs, resu, closedSolid, geomCtrl)) {
418     //std::cout << "Difference is Valid." << std::endl;
419     di << "Difference is Valid.\n";
420   } else {
421     //std::cout << "error : Difference is Not Valid !" << std::endl;
422     di << "error : Difference is Not Valid !\n";
423   }
424
425   return 0;
426 }
427 //=======================================================================
428
429 //  Modified by skv - Tue Apr 27 13:38:44 2004 Begin
430 //=======================================================================
431 //function : CHK
432 //purpose  : Checks a shape
433 //=======================================================================
434
435 // static Standard_Integer CHK(Draw_Interpretor& theCommands,
436 //                          Standard_Integer narg, const char** a)
437 // {
438 //   if (narg < 2) {
439 //     return 1;
440 //   }
441
442 //   Standard_Boolean doprint = Standard_True;
443 //   if (narg == 3) { if (!strcmp(a[2],"-short")) doprint = Standard_False; }
444
445 //   TopoDS_Shape S = DBRep::Get(a[1]);
446 //   if (S.IsNull()) {
447 //     std::cout<<"not a topological shape"<<std::endl;
448 //     return 1;
449 //   }
450
451 //   Standard_Boolean GeomCtrl = Standard_True;
452 //   if (!strcasecmp(a[0],"CHECKTOPSHAPE")) {
453 //     GeomCtrl = Standard_False;
454 //   }
455
456 //   BRepCheck_Analyzer ana(S,GeomCtrl);
457 //   if (ana.IsValid()) {
458 //     theCommands<<"This shape seems to be valid";
459 //   }
460 //   else {
461 //     theMap.Clear();
462 //     nbfaulty = 0;
463 //     lfaulty.Clear();
464 //     theMap.Clear();
465 //     if (doprint) {
466 //       Print(cout,ana,S);
467 //       std::cout<<"\n";
468 //       theMap.Clear();
469 //       if (nbfaulty !=0)
470 //      std::cout<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
471 //       std::cout<<std::endl;
472 //     }
473 //     else {
474 //       theCommands<<"This shape has faulty shapes";
475 //     }
476 //   }
477 //   return 0;
478 // }
479
480 //=======================================================================
481 //function : ContextualDump
482 //purpose  : Contextual (modeling) style of output.
483 //=======================================================================
484
485 //void ContextualDump(const BRepCheck_Analyzer &theAna,
486 //                  const TopoDS_Shape       &theShape)
487 void ContextualDump(Draw_Interpretor& theCommands,
488                     const BRepCheck_Analyzer &theAna,
489                     const TopoDS_Shape       &theShape)
490 {
491   theMap.Clear();
492   nbfaulty = 0;
493   lfaulty.Clear();
494
495   //Print(cout, theAna, theShape);
496   Standard_SStream aSStream;
497   Print(aSStream, theAna, theShape);
498   theCommands << aSStream;
499   //std::cout<<"\n";
500   theCommands<<"\n";
501   theMap.Clear();
502
503   if (nbfaulty !=0)
504     theCommands<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
505     //std::cout<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
506
507   //std::cout<<std::endl;
508   theCommands<<"\n";
509 }
510
511
512 //=======================================================================
513 //function : FillProblems
514 // purpose : auxilary for StructuralDump
515 //=======================================================================
516 static void FillProblems(const BRepCheck_Status stat,
517                          Handle(TColStd_HArray1OfInteger)& NbProblems)
518 {
519
520   const Standard_Integer anID = static_cast<Standard_Integer> (stat);
521
522   if((NbProblems->Upper() < anID) || (NbProblems->Lower() > anID))
523     return;
524
525   NbProblems->SetValue(anID, NbProblems->Value(anID)+1);
526
527 }
528
529
530 //=======================================================================
531 //function : GetProblemSub
532 // purpose : auxilary for StructuralDump
533 //=======================================================================
534 static void GetProblemSub(const BRepCheck_Analyzer& Ana,
535                           const TopoDS_Shape& Shape,
536                           Handle(TopTools_HSequenceOfShape)& sl,
537                           Handle(TColStd_HArray1OfInteger)& NbProblems,
538                           const TopAbs_ShapeEnum Subtype)
539 {
540   BRepCheck_ListIteratorOfListOfStatus itl;
541   TopExp_Explorer exp;
542   for (exp.Init(Shape,Subtype); exp.More(); exp.Next()) {
543     const Handle(BRepCheck_Result)& res = Ana.Result(exp.Current());
544
545     const TopoDS_Shape& sub = exp.Current();
546     for (res->InitContextIterator();
547          res->MoreShapeInContext(); 
548          res->NextShapeInContext()) {
549       if (res->ContextualShape().IsSame(Shape) && 
550           !Contains(theMap(sub),Shape)) {
551         theMap(sub).Append(Shape);
552         itl.Initialize(res->StatusOnShape());
553
554         if (itl.Value() != BRepCheck_NoError) {
555           Standard_Integer ii = 0;
556
557           for(ii=1; ii<=sl->Length(); ii++)
558             if(sl->Value(ii).IsSame(sub)) break;
559
560           if(ii>sl->Length()) {
561             sl->Append(sub);
562             FillProblems(itl.Value(),NbProblems);
563           }
564           for(ii=1; ii<=sl->Length(); ii++)
565             if(sl->Value(ii).IsSame(Shape)) break;
566           if(ii>sl->Length()) {
567             sl->Append(Shape);
568             FillProblems(itl.Value(),NbProblems);
569           }
570         }
571         break;
572       }
573     }
574   }
575 }
576
577
578 //=======================================================================
579 //function : GetProblemShapes
580 // purpose : auxilary for StructuralDump
581 //=======================================================================
582 static void GetProblemShapes(const BRepCheck_Analyzer& Ana,
583                              const TopoDS_Shape& Shape,
584                              Handle(TopTools_HSequenceOfShape)& sl,
585                              Handle(TColStd_HArray1OfInteger)& NbProblems)
586 {
587   for (TopoDS_Iterator iter(Shape); iter.More(); iter.Next()) {
588     GetProblemShapes(Ana,iter.Value(),sl, NbProblems);
589   }
590   TopAbs_ShapeEnum styp = Shape.ShapeType();
591   BRepCheck_ListIteratorOfListOfStatus itl;
592   if (!Ana.Result(Shape).IsNull() && !theMap.IsBound(Shape)) {
593     itl.Initialize(Ana.Result(Shape)->Status());
594
595     if (itl.Value() != BRepCheck_NoError) {
596       sl->Append(Shape);
597       FillProblems(itl.Value(),NbProblems);
598     }
599   }
600   if (!theMap.IsBound(Shape)) {
601     TopTools_ListOfShape thelist;
602     theMap.Bind(Shape, thelist);
603   }
604
605   switch (styp) {
606   case TopAbs_EDGE:
607     GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_VERTEX);
608     break;
609   case TopAbs_FACE:
610     GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_WIRE);
611     GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_EDGE);
612     GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_VERTEX);
613     break;
614   case TopAbs_SHELL:
615     break;
616   case TopAbs_SOLID:
617     GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_SHELL);
618     break;
619   default:
620     break;
621   }
622
623 }
624
625 //=======================================================================
626 //function : StructuralDump
627 //purpose  : Structural (data exchange) style of output.
628 //=======================================================================
629
630 //void StructuralDump(const BRepCheck_Analyzer &theAna,
631 //                    const Standard_CString   ShName,
632 //                    const Standard_CString   Pref,
633 //                  const TopoDS_Shape       &theShape)
634 void StructuralDump(Draw_Interpretor& theCommands,
635                     const BRepCheck_Analyzer &theAna,
636                     const Standard_CString   ShName,
637                     const Standard_CString   Pref,
638                     const TopoDS_Shape       &theShape)
639 {
640   Standard_Integer i;
641   //std::cout << "StructuralDump" << std::endl;
642   //std::cout << " -- The Shape " << ShName << " has problems :"<<std::endl;
643   //std::cout<<"  Check                                    Count"<<std::endl;
644   //std::cout<<" ------------------------------------------------"<<std::endl;
645   theCommands << " -- The Shape " << ShName << " has problems :\n";
646   theCommands<<"  Check                                    Count\n";
647   theCommands<<" ------------------------------------------------\n";
648
649   Handle(TColStd_HArray1OfInteger) NbProblems = new 
650                               TColStd_HArray1OfInteger(1,NumberOfStatus);
651   for(i=1; i<=NumberOfStatus; i++) NbProblems->SetValue(i,0);
652   Handle(TopTools_HSequenceOfShape) sl,slv,sle,slw,slf,sls,slo;
653   sl = new TopTools_HSequenceOfShape();
654   theMap.Clear();
655   GetProblemShapes(theAna, theShape, sl, NbProblems);
656   theMap.Clear();
657   
658   Standard_Integer aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnCurve);
659   if(NbProblems->Value(aProblemID) > 0)
660     theCommands<<"  Invalid Point on Curve ................... "<<NbProblems->Value(aProblemID)<<"\n";
661
662   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnCurveOnSurface);
663   if(NbProblems->Value(aProblemID)>0)
664     theCommands<<"  Invalid Point on CurveOnSurface .......... "<<NbProblems->Value(aProblemID)<<"\n";
665
666   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnSurface);
667   if(NbProblems->Value(aProblemID)>0)
668     theCommands<<"  Invalid Point on Surface ................. "<<NbProblems->Value(aProblemID)<<"\n";
669
670   aProblemID = static_cast<Standard_Integer>(BRepCheck_No3DCurve);
671   if(NbProblems->Value(aProblemID)>0)
672     theCommands<<"  No 3D Curve .............................. "<<NbProblems->Value(aProblemID)<<"\n";
673
674   aProblemID = static_cast<Standard_Integer>(BRepCheck_Multiple3DCurve);
675   if(NbProblems->Value(aProblemID)>0)
676     theCommands<<"  Multiple 3D Curve ........................ "<<NbProblems->Value(aProblemID)<<"\n";
677
678   aProblemID = static_cast<Standard_Integer>(BRepCheck_Invalid3DCurve);
679   if(NbProblems->Value(aProblemID)>0)
680     theCommands<<"  Invalid 3D Curve ......................... "<<NbProblems->Value(aProblemID)<<"\n";
681
682   aProblemID = static_cast<Standard_Integer>(BRepCheck_NoCurveOnSurface);
683   if(NbProblems->Value(aProblemID)>0)
684     theCommands<<"  No Curve on Surface ...................... "<<NbProblems->Value(aProblemID)<<"\n";
685
686   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidCurveOnSurface);
687   if(NbProblems->Value(aProblemID)>0)
688     theCommands<<"  Invalid Curve on Surface ................. "<<NbProblems->Value(aProblemID)<<"\n";
689
690   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidCurveOnClosedSurface);
691   if(NbProblems->Value(aProblemID)>0)
692     theCommands<<"  Invalid Curve on closed Surface .......... "<<NbProblems->Value(aProblemID)<<"\n";
693   
694   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidSameRangeFlag);
695   if(NbProblems->Value(aProblemID)>0)
696     theCommands<<"  Invalid SameRange Flag ................... "<<NbProblems->Value(aProblemID)<<"\n";
697   
698   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidSameParameterFlag);
699   if(NbProblems->Value(aProblemID)>0)
700     theCommands<<"  Invalid SameParameter Flag ............... "<<NbProblems->Value(aProblemID)<<"\n";
701   
702   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidDegeneratedFlag);
703   if(NbProblems->Value(aProblemID)>0)
704     theCommands<<"  Invalid Degenerated Flag ................. "<<NbProblems->Value(aProblemID)<<"\n";
705   
706   aProblemID = static_cast<Standard_Integer>(BRepCheck_FreeEdge);
707   if(NbProblems->Value(aProblemID)>0)
708     theCommands<<"  Free Edge ................................ "<<NbProblems->Value(aProblemID)<<"\n";
709   
710   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidMultiConnexity);
711   if(NbProblems->Value(aProblemID)>0)
712     theCommands<<"  Invalid MultiConnexity ................... "<<NbProblems->Value(aProblemID)<<"\n";
713   
714   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidRange);
715   if(NbProblems->Value(aProblemID)>0)
716     theCommands<<"  Invalid Range ............................ "<<NbProblems->Value(aProblemID)<<"\n";
717   
718   aProblemID = static_cast<Standard_Integer>(BRepCheck_EmptyWire);
719   if(NbProblems->Value(aProblemID)>0)
720     theCommands<<"  Empty Wire ............................... "<<NbProblems->Value(aProblemID)<<"\n";
721
722   aProblemID = static_cast<Standard_Integer>(BRepCheck_RedundantEdge);
723   if(NbProblems->Value(aProblemID)>0)
724     theCommands<<"  Redundant Edge ........................... "<<NbProblems->Value(aProblemID)<<"\n";
725
726   aProblemID = static_cast<Standard_Integer>(BRepCheck_SelfIntersectingWire);
727   if(NbProblems->Value(aProblemID)>0)
728     theCommands<<"  Self Intersecting Wire ................... "<<NbProblems->Value(aProblemID)<<"\n";
729
730   aProblemID = static_cast<Standard_Integer>(BRepCheck_NoSurface);
731   if(NbProblems->Value(aProblemID)>0)
732     theCommands<<"  No Surface ............................... "<<NbProblems->Value(aProblemID)<<"\n";
733
734   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidWire);
735   if(NbProblems->Value(aProblemID)>0)
736     theCommands<<"  Invalid Wire ............................. "<<NbProblems->Value(aProblemID)<<"\n";
737
738   aProblemID = static_cast<Standard_Integer>(BRepCheck_RedundantWire);
739   if(NbProblems->Value(aProblemID)>0)
740     theCommands<<"  Redundant Wire ........................... "<<NbProblems->Value(aProblemID)<<"\n";
741
742   aProblemID = static_cast<Standard_Integer>(BRepCheck_IntersectingWires);
743   if(NbProblems->Value(aProblemID)>0)
744     theCommands<<"  Intersecting Wires ....................... "<<NbProblems->Value(aProblemID)<<"\n";
745
746   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidImbricationOfWires);
747   if(NbProblems->Value(aProblemID)>0)
748     theCommands<<"  Invalid Imbrication of Wires ............. "<<NbProblems->Value(aProblemID)<<"\n";
749
750   aProblemID = static_cast<Standard_Integer>(BRepCheck_EmptyShell);
751   if(NbProblems->Value(aProblemID)>0)
752     theCommands<<"  Empty Shell .............................. "<<NbProblems->Value(aProblemID)<<"\n";
753
754   aProblemID = static_cast<Standard_Integer>(BRepCheck_RedundantFace);
755   if(NbProblems->Value(aProblemID)>0)
756     theCommands<<"  Redundant Face ........................... "<<NbProblems->Value(aProblemID)<<"\n";
757
758   aProblemID = static_cast<Standard_Integer>(BRepCheck_UnorientableShape);
759   if(NbProblems->Value(aProblemID)>0)
760     theCommands<<"  Unorientable Shape ....................... "<<NbProblems->Value(aProblemID)<<"\n";
761
762   aProblemID = static_cast<Standard_Integer>(BRepCheck_NotClosed);
763   if(NbProblems->Value(aProblemID)>0)
764     theCommands<<"  Not Closed ............................... "<<NbProblems->Value(aProblemID)<<"\n";
765
766   aProblemID = static_cast<Standard_Integer>(BRepCheck_NotConnected);
767   if(NbProblems->Value(aProblemID)>0)
768     theCommands<<"  Not Connected ............................ "<<NbProblems->Value(aProblemID)<<"\n";
769
770   aProblemID = static_cast<Standard_Integer>(BRepCheck_SubshapeNotInShape);
771   if(NbProblems->Value(aProblemID)>0)
772     theCommands<<"  Subshape not in Shape .................... "<<NbProblems->Value(aProblemID)<<"\n";
773
774   aProblemID = static_cast<Standard_Integer>(BRepCheck_BadOrientation);
775   if(NbProblems->Value(aProblemID)>0)
776     theCommands<<"  Bad Orientation .......................... "<<NbProblems->Value(aProblemID)<<"\n";
777
778   aProblemID = static_cast<Standard_Integer>(BRepCheck_BadOrientationOfSubshape);
779   if(NbProblems->Value(aProblemID)>0)
780     theCommands<<"  Bad Orientation of Subshape .............. "<<NbProblems->Value(aProblemID)<<"\n";
781
782   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidToleranceValue);
783   if(NbProblems->Value(aProblemID)>0)
784     theCommands<<"  Invalid tolerance value................... "<<NbProblems->Value(aProblemID)<<"\n";
785
786   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPolygonOnTriangulation);
787   if(NbProblems->Value(aProblemID)>0)
788     theCommands<<"  Invalid polygon on triangulation.......... "<<NbProblems->Value(aProblemID)<<"\n";
789
790   aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidImbricationOfShells);
791   if(NbProblems->Value(aProblemID)>0)
792     theCommands<<"  Invalid Imbrication of Shells............. "<<NbProblems->Value(aProblemID)<<"\n";
793  
794  aProblemID = static_cast<Standard_Integer>(BRepCheck_EnclosedRegion);
795   if(NbProblems->Value(aProblemID)>0)
796     theCommands<<"  Enclosed Region........................... "<<NbProblems->Value(aProblemID)<<"\n";
797
798   aProblemID = static_cast<Standard_Integer>(BRepCheck_CheckFail);
799   if(NbProblems->Value(aProblemID)>0)
800     theCommands<<"  checkshape failure........................ "<<NbProblems->Value(aProblemID)<<"\n";
801
802
803
804   theCommands<<" ------------------------------------------------\n";
805   theCommands<<"*** Shapes with problems : "<<sl->Length()<<"\n";
806
807   slv = new TopTools_HSequenceOfShape();
808   sle = new TopTools_HSequenceOfShape();
809   slw = new TopTools_HSequenceOfShape();
810   slf = new TopTools_HSequenceOfShape();
811   sls = new TopTools_HSequenceOfShape();
812   slo = new TopTools_HSequenceOfShape();
813
814   for(i=1; i<=sl->Length(); i++) {
815     TopoDS_Shape shi = sl->Value(i);
816     TopAbs_ShapeEnum sti = shi.ShapeType();
817     switch (sti) {
818       case TopAbs_VERTEX : slv->Append (shi); break;
819       case TopAbs_EDGE   : sle->Append (shi); break;
820       case TopAbs_WIRE   : slw->Append (shi); break;
821       case TopAbs_FACE   : slf->Append (shi); break;
822       case TopAbs_SHELL  : sls->Append (shi); break;
823       case TopAbs_SOLID  : slo->Append (shi); break;
824       default            : break;
825     }
826   }
827
828   BRep_Builder B;
829   if(slv->Length()>0) {
830     TopoDS_Compound comp;
831     B.MakeCompound(comp);
832     Standard_Integer nb = slv->Length();
833     for(i=1; i<=nb; i++)
834       B.Add(comp,slv->Value(i));
835     char aName[20];
836     Sprintf(aName,"%s_v",Pref);
837     DBRep::Set(aName,comp);
838     //std::cout<<"VERTEX        : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
839     if (nb > 9)
840       theCommands<<"VERTEX      : "<<nb<<" Items -> compound named "<<aName<<"\n";
841     else
842       theCommands<<"VERTEX      :  "<<nb<<" Items -> compound named "<<aName<<"\n";
843   }
844   if(sle->Length()>0) {
845     TopoDS_Compound comp;
846     B.MakeCompound(comp);
847     Standard_Integer nb = sle->Length();
848     for(i=1; i<=nb; i++)
849       B.Add(comp,sle->Value(i));
850     char aName[20];
851     Sprintf(aName,"%s_e",Pref);
852     DBRep::Set(aName,comp);
853     //std::cout<<"EDGE  : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
854     if (nb > 9)
855       theCommands<<"EDGE        : "<<nb<<" Items -> compound named "<<aName<<"\n";
856     else
857       theCommands<<"EDGE        :  "<<nb<<" Items -> compound named "<<aName<<"\n";
858   }
859   if(slw->Length()>0) {
860     TopoDS_Compound comp;
861     B.MakeCompound(comp);
862     Standard_Integer nb = slw->Length();
863     for(i=1; i<=nb; i++)
864       B.Add(comp,slw->Value(i));
865     char aName[20];
866     Sprintf(aName,"%s_w",Pref);
867     DBRep::Set(aName,comp);
868     //std::cout<<"WIRE  : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
869     if (nb > 9)
870       theCommands<<"WIRE        : "<<nb<<" Items -> compound named "<<aName<<"\n";
871     else
872       theCommands<<"WIRE        :  "<<nb<<" Items -> compound named "<<aName<<"\n";
873   }
874   if(slf->Length()>0) {
875     TopoDS_Compound comp;
876     B.MakeCompound(comp);
877     Standard_Integer nb = slf->Length();
878     for(i=1; i<=nb; i++)
879       B.Add(comp,slf->Value(i));
880     char aName[20];
881     Sprintf(aName,"%s_f",Pref);
882     DBRep::Set(aName,comp);
883     //std::cout<<"FACE  : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
884     if (nb > 9)
885       theCommands<<"FACE        : "<<nb<<" Items -> compound named "<<aName<<"\n";
886     else
887       theCommands<<"FACE        :  "<<nb<<" Items -> compound named "<<aName<<"\n";
888   }
889   if(sls->Length()>0) {
890     TopoDS_Compound comp;
891     B.MakeCompound(comp);
892     Standard_Integer nb = sls->Length();
893     for(i=1; i<=nb; i++)
894       B.Add(comp,sls->Value(i));
895     char aName[20];
896     Sprintf(aName,"%s_s",Pref);
897     DBRep::Set(aName,comp);
898     //std::cout<<"SHELL : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
899     if (nb > 9)
900       theCommands<<"SHELL       : "<<nb<<" Items -> compound named "<<aName<<"\n";
901     else
902       theCommands<<"SHELL       :  "<<nb<<" Items -> compound named "<<aName<<"\n";
903   }
904   if(slo->Length()>0) {
905     TopoDS_Compound comp;
906     B.MakeCompound(comp);
907     Standard_Integer nb = slo->Length();
908     for(i=1; i<=nb; i++)
909       B.Add(comp,slo->Value(i));
910     char aName[20];
911     Sprintf(aName,"%s_o",Pref);
912     DBRep::Set(aName,comp);
913     //std::cout<<"SOLID : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
914     if (nb > 9)
915       theCommands<<"SOLID       : "<<nb<<" Items -> compound named "<<aName<<"\n";
916     else
917       theCommands<<"SOLID       :  "<<nb<<" Items -> compound named "<<aName<<"\n";
918   }
919 }
920
921 //=======================================================================
922 //function : checkshape
923 //purpose  : Checks a shape
924 //=======================================================================
925
926 static Standard_Integer checkshape(Draw_Interpretor& theCommands,
927                                    Standard_Integer narg, const char** a)
928 {
929   if (narg == 1) {
930     //std::cout << std::endl;
931     //std::cout << "Usage : checkshape [-top] shape [result] [-short]" << std::endl;
932     //std::cout << std::endl;
933     //std::cout << "Where :" << std::endl;
934     //std::cout << "   -top   - check topology only." << std::endl;
935     //std::cout << "   shape  - the name of the shape to test." << std::endl;
936     //std::cout << "   result - the prefix of the output shape names. If it is used, structural" << std::endl;
937     //std::cout << "            output style will be used. Otherwise - contextual one." << std::endl;
938     //std::cout << "   -short - short description of check." << std::endl;
939     theCommands << "\n";
940     theCommands << "Usage : checkshape [-top] shape [result] [-short]\n";
941     theCommands << "\n";
942     theCommands << "Where :\n";
943     theCommands << "   -top   - check topology only.\n";
944     theCommands << "   shape  - the name of the shape to test.\n";
945     theCommands << "   result - the prefix of the output shape names. If it is used, structural\n";
946     theCommands << "            output style will be used. Otherwise - contextual one.\n";
947     theCommands << "   -short - short description of check.\n";
948
949     return 0;
950   }
951
952   if (narg > 5) {
953     //std::cout << "Invalid number of args!!!" << std::endl;
954     //std::cout << "No args to have help." << std::endl;
955     theCommands << "Invalid number of args!!!\n";
956     theCommands << "No args to have help.\n";
957
958     return 1;
959   }
960
961   Standard_Boolean aGeomCtrl = Standard_True;
962   Standard_Integer aCurInd  = 1;
963
964   if (!strcmp(a[1],"-top")) {
965     aGeomCtrl = Standard_False;
966     aCurInd++;
967   }
968
969   if (aCurInd > narg - 1) {
970     //std::cout << "Invalid number of args!!!" << std::endl;
971     //std::cout << "No args to have help." << std::endl;
972     theCommands << "Invalid number of args!!!\n";
973     theCommands << "No args to have help.\n";
974
975     return 1;
976   }
977
978   Standard_CString aShapeName = a[aCurInd];
979   TopoDS_Shape     aShape     = DBRep::Get(aShapeName);
980
981   if (aShape.IsNull()) {
982     //std::cout << a[aCurInd] << " is not a topological shape!!!" << std::endl;
983     theCommands << a[aCurInd] << " is not a topological shape!!!\n";
984
985     return 1;
986   }
987
988   Standard_Boolean IsShortDump   = Standard_False;
989   Standard_Boolean IsContextDump = Standard_True;
990   Standard_Integer aBackInd      = narg - 1;
991
992   if (aCurInd < aBackInd) {
993     if (!strcmp(a[aBackInd],"-short")) {
994       IsShortDump = Standard_True;
995       aBackInd--;
996     }
997   }
998
999   if (aCurInd < aBackInd - 1) {
1000     //std::cout << "Invalid number of args!!!" << std::endl;
1001     //std::cout << "No args to have help." << std::endl;
1002     theCommands << "Invalid number of args!!!\n";
1003     theCommands << "No args to have help.\n";
1004
1005     return 1;
1006   } else if (aCurInd < aBackInd) {
1007     IsContextDump = Standard_False;
1008   }
1009
1010   try {
1011     OCC_CATCH_SIGNALS
1012     BRepCheck_Analyzer anAna(aShape,aGeomCtrl);
1013     Standard_Boolean   isValid = anAna.IsValid();
1014
1015     if (isValid) {
1016       if (IsContextDump) {
1017         theCommands << "This shape seems to be valid";
1018       } else {
1019         theCommands << " -- The Shape " << aShapeName << " looks OK";
1020       }
1021     } else {
1022       if (IsShortDump) {
1023         theCommands<<"This shape has faulty shapes";
1024       } else {
1025         if (IsContextDump) {
1026           //ContextualDump(anAna, aShape);
1027           ContextualDump(theCommands, anAna, aShape);
1028         } else {
1029           Standard_CString aPref = a[aCurInd+1];
1030           //StructuralDump(anAna, aShapeName, aPref, aShape);
1031           StructuralDump(theCommands, anAna, aShapeName, aPref, aShape);
1032         }
1033       }
1034     }
1035   }
1036   catch(Standard_Failure const& anException) {
1037     theCommands<<"checkshape exception : ";
1038     theCommands << anException.GetMessageString();
1039     theCommands<<"\n";
1040     return 1;
1041   }
1042
1043   return 0;
1044 }
1045 //  Modified by skv - Tue Apr 27 13:38:24 2004 End
1046 /***************************************************************/
1047 static void InitEpsSurf(Standard_Real& epsnl,Standard_Real& epsdis, Standard_Real& epsangk1, 
1048                         Standard_Real& epsangk2, Standard_Real& epsangn1, 
1049                         Standard_Real& perce,Standard_Real& maxlen )
1050
1051   epsnl  = 0.001;
1052   epsdis = 0.001;
1053   epsangk1 = 0.001 ; 
1054   epsangk2 = 0.001;
1055   epsangn1 = 0.001 ; 
1056   perce = 0.01;
1057   maxlen = 10000 ;
1058 }
1059
1060 static Standard_Integer shapeG1continuity (Draw_Interpretor& di, Standard_Integer n, const char** a)
1061
1062 { Standard_Real epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen;
1063   Standard_Integer nbeval;  
1064   InitEpsSurf(epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen);
1065   Standard_Boolean ISG1=Standard_True;
1066   if (n<4) return 1;
1067   TopoDS_Face face1,face2;
1068   Standard_Real f1,f2,l1,l2;
1069   TopoDS_Shape shape = DBRep::Get(a[1],TopAbs_SHAPE);
1070   if (shape.IsNull()) return 1;
1071   TopoDS_Shape  edge  = DBRep::Get(a[2],TopAbs_EDGE);
1072   if (edge.IsNull()) return 1;
1073 // calcul des deux faces 
1074   TopTools_IndexedDataMapOfShapeListOfShape lface;
1075   TopExp::MapShapesAndAncestors(shape,TopAbs_EDGE,TopAbs_FACE,lface);
1076   const TopTools_ListOfShape& lfac = lface.FindFromKey(edge);
1077
1078   Standard_Integer nelem= lfac.Extent();
1079   if(nelem!=2) return 1; 
1080   TopTools_ListIteratorOfListOfShape It;
1081   It.Initialize(lfac);
1082   face1=TopoDS::Face(It.Value());
1083   It.Next();
1084   face2=TopoDS::Face(It.Value());
1085
1086   Standard_Boolean IsSeam = face1.IsEqual(face2);
1087     
1088 // calcul des deux pcurves 
1089   const Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface
1090                                (TopoDS::Edge(edge),face1,f1,l1);
1091   if (c1.IsNull()) return 1;
1092
1093   if (IsSeam)
1094     edge.Reverse();
1095   const  Handle(Geom2d_Curve) c2  = BRep_Tool::CurveOnSurface
1096                                (TopoDS::Edge(edge),face2,f2,l2);
1097   if (c2.IsNull()) return 1;
1098         
1099    Handle(Geom2d_Curve) curv1= new Geom2d_TrimmedCurve(c1,f1,l1);
1100    
1101    Handle(Geom2d_Curve) curv2= new Geom2d_TrimmedCurve(c2,f2,l2);  
1102    
1103 // calcul dees deux surfaces 
1104   TopLoc_Location L1,L2; 
1105   TopoDS_Face aLocalFace = face1;
1106   const Handle(Geom_Surface)& s1 = BRep_Tool::Surface(aLocalFace,L1);
1107 //  const Handle(Geom_Surface)& s1 =
1108 //    BRep_Tool::Surface(TopoDS::Face(face1),L1);
1109   if (s1.IsNull()) return 1;
1110   aLocalFace = face2;
1111   const Handle(Geom_Surface)& s2 = BRep_Tool::Surface(aLocalFace,L2);
1112 //  const Handle(Geom_Surface)& s2 =
1113 //    BRep_Tool::Surface(TopoDS::Face(face2),L2); 
1114   if (s2.IsNull()) return 1;     
1115
1116
1117    Handle(Geom_Surface) surf1 = Handle(Geom_Surface)::
1118                                  DownCast(s1->Transformed(L1.Transformation()));
1119    if (surf1.IsNull()) return 1;
1120    Handle(Geom_Surface) surf2 = Handle(Geom_Surface)::
1121                                 DownCast(s2->Transformed(L2.Transformation()));
1122    if (surf2.IsNull()) return 1;
1123    
1124  
1125
1126   nbeval = (Standard_Integer ) Draw::Atof( a[3]);
1127
1128   switch(n)
1129   { 
1130   case 7  : epsG1 = Draw::Atof(a[6]);
1131     Standard_FALLTHROUGH
1132   case 6  : epsC0 = Draw::Atof(a[5]);
1133     Standard_FALLTHROUGH
1134   case 5  : epsnl = Draw::Atof(a[4]);
1135     Standard_FALLTHROUGH
1136   case 4  : break;
1137   default : return 1;
1138   }
1139
1140
1141   Standard_Real pard1, parf1, U, Uf, deltaU, nb = 0;
1142   Standard_Boolean isconti = Standard_True;
1143   Standard_Boolean isdone = Standard_True;
1144   pard1 = curv1->FirstParameter();
1145   parf1 = curv1->LastParameter();
1146   Standard_Real  MaxG0Value=0, MaxG1Angle=0; 
1147   U = Min( pard1,parf1);
1148   Uf = Max (pard1,parf1);
1149
1150   deltaU =  Abs(parf1- pard1)/nbeval;
1151       
1152   do  
1153      { if ( nb == nbeval) 
1154           { LocalAnalysis_SurfaceContinuity res(curv1, curv2, Uf,surf1, surf2,            GeomAbs_G1, epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen );
1155             isdone = res.IsDone();
1156            if ( isdone) { isconti = res.IsG1();
1157                              if (isconti) 
1158                               {if (res.C0Value()>MaxG0Value)  MaxG0Value = res.C0Value();
1159                                if (res.G1Angle ()>MaxG1Angle) MaxG1Angle = res.G1Angle();}}
1160             else isconti = Standard_False;}
1161                     
1162           else {LocalAnalysis_SurfaceContinuity res (curv1, curv2, (U+nb*deltaU                 ), surf1,surf2, GeomAbs_G1,epsnl,epsC0, epsC1, epsC2, epsG1,
1163                  percent,maxlen);
1164                  isdone = res.IsDone();
1165                  if ( isdone) { isconti = res.IsG1();
1166                                   if ( nb == 0) { MaxG0Value = res.C0Value();
1167                                                   MaxG1Angle = res.G1Angle();}
1168                                   if (res.C0Value()> MaxG0Value)  MaxG0Value = res.C0Value();
1169                                   if (res.G1Angle()> MaxG1Angle)  MaxG1Angle= res.G1Angle();;}
1170                                   
1171                  else isconti = Standard_False;}
1172        if (!isconti) ISG1=Standard_False;                             
1173        nb++;
1174        
1175      }
1176    while ((nb<nbeval)&& isdone );
1177
1178   //if (!isdone)  { std::cout<<" Problem in computation "<<std::endl; return 1;}
1179   //if (ISG1) 
1180   //    {std::cout<<" the continuity is G1 "<<std::endl;}
1181   //else { std::cout<<" the continuity is not G1  "<<std::endl;}
1182   //std::cout<<"MaxG0Value :"<< MaxG0Value << std::endl;
1183   //std::cout<<"MaxG1Angle:"<<  MaxG1Angle << std::endl;
1184   if (!isdone)  { di<<" Problem in computation \n"; return 1;}
1185   if (ISG1) 
1186       {di<<" the continuity is G1 \n";}
1187   else { di<<" the continuity is not G1  \n";}
1188   di<<"MaxG0Value :"<< MaxG0Value << "\n";
1189   di<<"MaxG1Angle:"<<  MaxG1Angle << "\n";
1190   return 0;
1191 }
1192 /*****************************************************************************/
1193 static Standard_Integer shapeG0continuity (Draw_Interpretor& di, Standard_Integer n, const char** a)
1194
1195 { Standard_Real epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen; 
1196   Standard_Integer nbeval;
1197   Standard_Boolean ISG0;
1198   InitEpsSurf(epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen  );
1199
1200   if (n<4) return 1;
1201   TopoDS_Face face1,face2;
1202   Standard_Real f1,f2,l1,l2;
1203   TopoDS_Shape shape = DBRep::Get(a[1],TopAbs_SHAPE);
1204   if (shape.IsNull()) return 1;
1205   TopoDS_Shape  edge  = DBRep::Get(a[2],TopAbs_EDGE);
1206   if (edge.IsNull()) return 1;
1207 // calcul des deux faces 
1208   TopTools_IndexedDataMapOfShapeListOfShape lface;
1209   TopExp::MapShapesAndAncestors(shape,TopAbs_EDGE,TopAbs_FACE,lface);
1210   const TopTools_ListOfShape& lfac = lface.FindFromKey(edge);
1211
1212   Standard_Integer nelem= lfac.Extent();
1213   if(nelem!=2) return 1; 
1214   TopTools_ListIteratorOfListOfShape It;
1215   It.Initialize(lfac);
1216   face1=TopoDS::Face(It.Value());
1217   It.Next();
1218   face2=TopoDS::Face(It.Value());
1219     
1220   Standard_Boolean IsSeam = face1.IsEqual(face2);
1221     
1222 // calcul des deux pcurves 
1223   const Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface
1224                                (TopoDS::Edge(edge),face1,f1,l1);
1225   if (c1.IsNull()) return 1;
1226   
1227   if (IsSeam)
1228     edge.Reverse();
1229   const  Handle(Geom2d_Curve) c2  = BRep_Tool::CurveOnSurface
1230                                (TopoDS::Edge(edge),face2,f2,l2);
1231   if (c2.IsNull()) return 1;
1232         
1233    Handle(Geom2d_Curve) curv1= new Geom2d_TrimmedCurve(c1,f1,l1);
1234    
1235    Handle(Geom2d_Curve) curv2= new Geom2d_TrimmedCurve(c2,f2,l2);  
1236    
1237 // calcul des deux surfaces 
1238   TopLoc_Location L1,L2; 
1239   TopoDS_Face aLocalFace = face1;
1240   const Handle(Geom_Surface)& s1 = BRep_Tool::Surface(aLocalFace,L1);
1241 //  const Handle(Geom_Surface)& s1 =
1242 //    BRep_Tool::Surface(TopoDS::Face(face1),L1);
1243   if (s1.IsNull()) return 1;
1244   aLocalFace = face2;
1245   const Handle(Geom_Surface)& s2 = BRep_Tool::Surface(aLocalFace,L2); 
1246 //  const Handle(Geom_Surface)& s2 =
1247 //    BRep_Tool::Surface(TopoDS::Face(face2),L2); 
1248   if (s2.IsNull()) return 1;     
1249
1250
1251    Handle(Geom_Surface) surf1 = Handle(Geom_Surface)::
1252                                  DownCast(s1->Transformed(L1.Transformation()));
1253    if (surf1.IsNull()) return 1;
1254    Handle(Geom_Surface) surf2 = Handle(Geom_Surface)::
1255                                 DownCast(s2->Transformed(L2.Transformation()));
1256    if (surf2.IsNull()) return 1;
1257    
1258  
1259
1260   nbeval = (Standard_Integer ) Draw::Atof( a[3]);
1261
1262   switch(n)
1263   { 
1264   case 6  : epsC0   = Draw::Atof(a[5]);
1265     Standard_FALLTHROUGH
1266   case 5  : epsnl    = Draw::Atof(a[4]);
1267     Standard_FALLTHROUGH
1268   case 4  : break;
1269   default : return 1;
1270   }
1271
1272   Standard_Real pard1, parf1, U, Uf, deltaU, nb = 0;
1273   Standard_Boolean isconti = Standard_True;
1274   Standard_Boolean isdone = Standard_True;
1275   pard1 = curv1->FirstParameter();
1276   parf1 = curv1->LastParameter();
1277   Standard_Real  MaxG0Value=0;
1278   U = Min( pard1,parf1);
1279   Uf = Max (pard1,parf1);
1280
1281   deltaU =  Abs(parf1- pard1)/nbeval;
1282   ISG0=Standard_True;    
1283   do  
1284      { if ( nb == nbeval) 
1285           { LocalAnalysis_SurfaceContinuity res (curv1, curv2, Uf,surf1, surf2, GeomAbs_C0,epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen  );
1286             isdone = res.IsDone();
1287             if ( isdone) { isconti = res.IsC0( );
1288                           if (isconti) 
1289                           if (res.C0Value()>MaxG0Value)  MaxG0Value= res.C0Value();}  
1290             else isconti = Standard_False;}
1291                     
1292        else {LocalAnalysis_SurfaceContinuity res (curv1, curv2, (U+nb*deltaU), surf1, surf2, GeomAbs_C0,epsnl,epsC0, epsC1, epsC2, epsG1, percent,maxlen );
1293              isdone = res.IsDone();
1294              if ( isdone) { isconti = res.IsC0() ;
1295                                   if ( nb == 0) { MaxG0Value = res.C0Value();}
1296                                   if (res.C0Value()> MaxG0Value)  MaxG0Value = res.C0Value();}
1297                                   
1298                  else isconti = Standard_False;}
1299                               
1300        nb++;
1301        if (!isconti) ISG0=Standard_False;
1302        
1303      }
1304    while ((nb<nbeval)&& isdone );
1305
1306   //f (!isdone)  { std::cout<<" Problem in computation "<<std::endl; return 1;}
1307   //if (ISG0) 
1308   //    {std::cout<<" the continuity is G0 "<<std::endl;}
1309
1310   //else { std::cout<<" the continuity is not G0  "<<std::endl;}
1311   //std::cout<<"MaxG0Value :"<< MaxG0Value << std::endl;
1312   if (!isdone)  { di<<" Problem in computation \n"; return 1;}
1313   if (ISG0) 
1314       {di<<" the continuity is G0 \n";}
1315
1316   else { di<<" the continuity is not G0  \n";}
1317   di<<"MaxG0Value :"<< MaxG0Value << "\n";
1318   return 0;
1319 }
1320 /*****************************************************************************************/
1321 static Standard_Integer shapeG2continuity (Draw_Interpretor& di, Standard_Integer n, const char** a)
1322
1323 { Standard_Real epsnl,epsC0, epsC1, epsC2, epsG1, percent,maxlen;
1324   Standard_Boolean ISG2=Standard_True;
1325   Standard_Integer nbeval;
1326   Standard_Real MaxG0Value=0,MaxG1Angle=0,MaxG2Curvature=0;
1327   InitEpsSurf(epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen );
1328
1329   if (n<4) return 1;
1330   TopoDS_Face face1,face2;
1331   Standard_Real f1,f2,l1,l2;
1332   TopoDS_Shape shape = DBRep::Get(a[1],TopAbs_SHAPE);
1333   if (shape.IsNull()) return 1;
1334   TopoDS_Shape  edge  = DBRep::Get(a[2],TopAbs_EDGE);
1335   if (edge.IsNull()) return 1;
1336 // calcul des deux faces 
1337   TopTools_IndexedDataMapOfShapeListOfShape lface;
1338   TopExp::MapShapesAndAncestors(shape,TopAbs_EDGE,TopAbs_FACE,lface);
1339   const TopTools_ListOfShape& lfac = lface.FindFromKey(edge);
1340
1341   Standard_Integer nelem= lfac.Extent();
1342   if(nelem!=2) return 1; 
1343   TopTools_ListIteratorOfListOfShape It;
1344   It.Initialize(lfac);
1345   face1=TopoDS::Face(It.Value());
1346   It.Next();
1347   face2=TopoDS::Face(It.Value());
1348
1349   Standard_Boolean IsSeam = face1.IsEqual(face2);
1350   
1351 // calcul des deux pcurves 
1352   const Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface
1353                                (TopoDS::Edge(edge),face1,f1,l1);
1354   if (c1.IsNull()) return 1;
1355   
1356   if (IsSeam)
1357     edge.Reverse();
1358   const  Handle(Geom2d_Curve) c2  = BRep_Tool::CurveOnSurface
1359                                (TopoDS::Edge(edge),face2,f2,l2);
1360   if (c2.IsNull()) return 1;
1361         
1362    Handle(Geom2d_Curve) curv1= new Geom2d_TrimmedCurve(c1,f1,l1);
1363    
1364    Handle(Geom2d_Curve) curv2= new Geom2d_TrimmedCurve(c2,f2,l2);  
1365    
1366 // calcul des deux surfaces 
1367   TopLoc_Location L1,L2; 
1368   TopoDS_Face aLocalFace = face1;
1369   const Handle(Geom_Surface)& s1 = BRep_Tool::Surface(aLocalFace,L1);
1370 //  const Handle(Geom_Surface)& s1 = 
1371 //    BRep_Tool::Surface(TopoDS::Face(face1),L1);
1372   if (s1.IsNull()) return 1;
1373   aLocalFace = face2;
1374   const Handle(Geom_Surface)& s2 = BRep_Tool::Surface(aLocalFace,L2); 
1375 //  const Handle(Geom_Surface)& s2 =
1376 //    BRep_Tool::Surface(TopoDS::Face(face2),L2); 
1377   if (s2.IsNull()) return 1;     
1378
1379
1380    Handle(Geom_Surface) surf1 = Handle(Geom_Surface)::
1381                                  DownCast(s1->Transformed(L1.Transformation()));
1382    if (surf1.IsNull()) return 1;
1383    Handle(Geom_Surface) surf2 = Handle(Geom_Surface)::
1384                                 DownCast(s2->Transformed(L2.Transformation()));
1385    if (surf2.IsNull()) return 1;
1386    
1387  
1388
1389   nbeval = (Standard_Integer ) Draw::Atof( a[3]);
1390
1391   switch(n)
1392   { 
1393   case 9  :  maxlen = Draw::Atof(a[8]);
1394     Standard_FALLTHROUGH
1395   case 8   : percent = Draw::Atof(a[7]);      
1396     Standard_FALLTHROUGH
1397   case 7   : epsG1 = Draw::Atof(a[6]);
1398     Standard_FALLTHROUGH
1399   case 6  :  epsC0 = Draw::Atof(a[5]);
1400     Standard_FALLTHROUGH
1401   case 5  :  epsnl = Draw::Atof(a[4]);
1402     Standard_FALLTHROUGH
1403   case 4  : break;
1404   default : return 1;
1405   }
1406
1407
1408   Standard_Real pard1, parf1, U, Uf, deltaU, nb = 0;
1409   Standard_Boolean isconti = Standard_True;
1410   Standard_Boolean isdone = Standard_True;
1411   pard1 = curv1->FirstParameter();
1412   parf1 = curv1->LastParameter();
1413   U = Min( pard1,parf1);
1414   Uf = Max (pard1,parf1);
1415
1416   deltaU =  Abs(parf1- pard1)/nbeval;
1417       
1418   do  
1419      { if ( nb == nbeval) 
1420           { LocalAnalysis_SurfaceContinuity res (curv1, curv2, Uf,surf1, surf2,             GeomAbs_G2,epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen );
1421             isdone = res.IsDone();
1422             if (isdone){isconti = res.IsG2();
1423                         if (isconti) 
1424                         {if(res.C0Value()>MaxG0Value) MaxG0Value=res.C0Value();
1425                          if(res.G1Angle()>MaxG1Angle) MaxG1Angle=res.G1Angle();
1426                          if(res.G2CurvatureGap()>MaxG2Curvature) 
1427                            MaxG2Curvature=res.G2CurvatureGap();
1428                         }}
1429             else isconti = Standard_False;}
1430                     
1431        else { LocalAnalysis_SurfaceContinuity res (curv1, curv2, (U+nb*deltaU), surf1,surf2, GeomAbs_G2,epsnl,epsC0, epsC1, epsC2, epsG1,percent,maxlen );
1432              isdone = res.IsDone();
1433              if ( isdone) {isconti = res.IsG2();
1434                            if (nb==0){MaxG0Value=res.C0Value();
1435                                       MaxG1Angle=res.G1Angle();
1436                                       MaxG2Curvature=res.G2CurvatureGap();}
1437                            if(res.C0Value()>MaxG0Value) 
1438                                 MaxG0Value=res.C0Value();
1439                            if(res.G1Angle()>MaxG1Angle) 
1440                                 MaxG1Angle=res.G1Angle();
1441                            if(res.G2CurvatureGap()>MaxG2Curvature) 
1442                               MaxG2Curvature=res.G2CurvatureGap();}
1443                  else isconti = Standard_False;}
1444                               
1445        nb++;
1446        if (!isconti) ISG2=Standard_False;
1447        
1448      }
1449    while ((nb<nbeval)&& isdone );
1450
1451   //if (!isdone)  { std::cout<<" Problem in computation "<<std::endl; return 1;}
1452   //if (ISG2) 
1453   //std::cout<<" the continuity is G2 "<<std::endl;
1454   //else std::cout<<" the continuity is not G2  "<<std::endl;
1455   //std::cout<<"MaxG0Value :"<< MaxG0Value << std::endl;
1456   //std::cout<<"MaxG1Angle:"<<  MaxG1Angle << std::endl;
1457   //std::cout<<"MaxG2Curvature:"<<MaxG2Curvature<<std::endl;
1458   if (!isdone)  { di<<" Problem in computation \n"; return 1;}
1459   if (ISG2) 
1460   di<<" the continuity is G2 \n";
1461   else di<<" the continuity is not G2  \n";
1462   di<<"MaxG0Value :"<< MaxG0Value << "\n";
1463   di<<"MaxG1Angle:"<<  MaxG1Angle << "\n";
1464   di<<"MaxG2Curvature:"<<MaxG2Curvature<<"\n";
1465   return 0;
1466 }
1467
1468
1469 //=======================================================================
1470 //function : clintedge
1471 //purpose  : 
1472 //=======================================================================
1473 static Standard_Integer clintedge(Draw_Interpretor& di,
1474                                          Standard_Integer narg, const char** a)
1475 {
1476   char newname[255];
1477
1478   if (narg < 2) {
1479     //std::cout << "Usage: clintedge shape" << std::endl;
1480     di << "Usage: clintedge shape\n";
1481     return 1;
1482   }
1483   TopoDS_Shape S = DBRep::Get(a[1]);
1484
1485   TopTools_DataMapOfShapeListOfShape mymap;
1486   TopOpeBRepTool_PurgeInternalEdges mypurgealgo(S);
1487   Standard_Integer nbedges = mypurgealgo.NbEdges();
1488   if (nbedges > 0)
1489   {
1490     //std::cout<<nbedges<<" internal (or external) edges to be removed"<<std::endl;
1491     di<<nbedges<<" internal (or external) edges to be removed\n";
1492
1493     Standard_Integer i = 1;
1494     char* temp = newname;
1495
1496     Sprintf(newname,"%s_%d",a[1],i);
1497     DBRep::Set(temp,mypurgealgo.Shape());
1498     //std::cout<<newname<<" ";
1499     di<<newname<<" ";
1500
1501     //std::cout<<std::endl;
1502     di<<"\n";
1503   }
1504   else
1505     di << "no internal (or external) edges\n";
1506     //std::cout << "no internal (or external) edges"<<std::endl;
1507
1508   return 0;
1509 }
1510
1511
1512 //=======================================================================
1513 //function : facintedge
1514 //purpose  : 
1515 //=======================================================================
1516 static Standard_Integer facintedge(Draw_Interpretor& di,
1517                                          Standard_Integer narg, const char** a)
1518 {
1519   char newname[255];
1520
1521   if (narg < 2) {
1522     //std::cout << "Usage: facintedge shape" << std::endl;
1523     di << "Usage: facintedge shape\n";
1524     return 1;
1525   }
1526   TopoDS_Shape S = DBRep::Get(a[1]);
1527
1528   TopTools_DataMapOfShapeListOfShape mymap;
1529   TopOpeBRepTool_PurgeInternalEdges mypurgealgo(S);
1530   mypurgealgo.Faces(mymap);
1531
1532   Standard_Integer i = 1;
1533   char* temp = newname;
1534
1535   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itFacEdg;
1536   for (itFacEdg.Initialize(mymap); itFacEdg.More(); itFacEdg.Next()) {
1537       Sprintf(newname,"%s_%d",a[1],i);
1538       DBRep::Set(temp,itFacEdg.Key());
1539       //std::cout<<newname<<" ";
1540       di<<newname<<" ";
1541       i++;
1542     }
1543
1544   //std::cout<<std::endl;
1545   di<<"\n";
1546
1547   return 0;
1548 }
1549
1550 //=======================================================================
1551 //function : fuseedge
1552 //purpose  : 
1553 //=======================================================================
1554 static Standard_Integer fuseedge(Draw_Interpretor& di,
1555                                          Standard_Integer narg, const char** a)
1556 {
1557   char newname[255];
1558
1559   if (narg < 2) {
1560     //std::cout << "Usage: fuseedge shape" << std::endl;
1561     di << "Usage: fuseedge shape\n";
1562     return 1;
1563   }
1564   TopoDS_Shape S = DBRep::Get(a[1]);
1565
1566   TopTools_DataMapOfIntegerListOfShape mymap;
1567   //TopOpeBRepTool_FuseEdges myfusealgo(S);
1568   BRepLib_FuseEdges myfusealgo(S);
1569   myfusealgo.SetConcatBSpl();
1570   Standard_Integer nbvertices;
1571   nbvertices = myfusealgo.NbVertices();
1572
1573   if (nbvertices > 0) {
1574
1575     //std::cout<<nbvertices<<" vertices to be removed"<<std::endl;
1576     di<<nbvertices<<" vertices to be removed\n";
1577
1578     Standard_Integer i = 1;
1579     char* temp = newname;
1580
1581     Sprintf(newname,"%s_%d",a[1],i);
1582     DBRep::Set(temp,myfusealgo.Shape());
1583     //std::cout<<newname<<" ";
1584     di<<newname<<" ";
1585
1586     //std::cout<<std::endl;
1587     di<<"\n";
1588   }
1589   else
1590     di << "no vertices to remove\n";
1591     //std::cout << "no vertices to remove"<<std::endl;
1592
1593   return 0;
1594 }
1595
1596
1597 //=======================================================================
1598 //function : listfuseedge
1599 //purpose  : 
1600 //=======================================================================
1601 static Standard_Integer listfuseedge(Draw_Interpretor& di,
1602                                          Standard_Integer narg, const char** a)
1603 {
1604   char newname[255];
1605
1606   if (narg < 2) {
1607     //std::cout << "Usage: listfuseedge shape" << std::endl;
1608     di << "Usage: listfuseedge shape\n";
1609     return 1;
1610   }
1611   TopoDS_Shape S = DBRep::Get(a[1]);
1612
1613   TopTools_DataMapOfIntegerListOfShape mymap;
1614   BRepLib_FuseEdges myfusealgo(S);
1615   myfusealgo.Edges(mymap);
1616
1617   Standard_Integer i;
1618   char* temp = newname;
1619
1620   TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape itLstEdg;
1621   for (itLstEdg.Initialize(mymap); itLstEdg.More(); itLstEdg.Next()) {
1622       const Standard_Integer& iLst = itLstEdg.Key();
1623       const TopTools_ListOfShape& LmapEdg = mymap.Find(iLst);
1624       TopTools_ListIteratorOfListOfShape itEdg; 
1625       i = 1;
1626       for (itEdg.Initialize(LmapEdg); itEdg.More(); itEdg.Next()) {
1627         Sprintf(newname,"%s_%d_%d",a[1],iLst,i);
1628         DBRep::Set(temp,itEdg.Value());
1629         //std::cout<<newname<<" ";
1630         di<<newname<<" ";
1631         i++;
1632       }
1633
1634     }
1635
1636   //std::cout<<std::endl;
1637   di<<"\n";
1638
1639   return 0;
1640 }
1641
1642 //=======================================================================
1643 //function : tolsphere
1644 //purpose  : 
1645 //=======================================================================
1646 static Standard_Integer tolsphere(Draw_Interpretor& di, Standard_Integer n, const char** a)
1647 {
1648   if (n != 2)
1649   {
1650     di << "use toolsphere shape\n";
1651     return 1;
1652   }
1653
1654   TopoDS_Shape aS = DBRep::Get(a[1]);
1655   if (aS.IsNull())
1656   {
1657     di << "No such shape " << a[1] << "\n";
1658     return 1;
1659   }
1660
1661   TopTools_IndexedMapOfShape aMapV;
1662   TopExp::MapShapes(aS, TopAbs_VERTEX, aMapV);
1663   for (Standard_Integer i = 1; i <= aMapV.Extent(); i++)
1664   {
1665     const TopoDS_Vertex& aV = TopoDS::Vertex(aMapV.FindKey(i));
1666     Standard_Real aRadius = BRep_Tool::Tolerance(aV);
1667     gp_Pnt aCenter = BRep_Tool::Pnt(aV);
1668     Handle(Geom_Surface) aSph = new Geom_SphericalSurface(gp_Ax2(aCenter,gp::DZ()), aRadius);
1669     TCollection_AsciiString aName(a[1]);
1670     aName = aName + "_v" + i;
1671     DrawTrSurf::Set(aName.ToCString(), aSph);
1672     di << aName << " ";
1673   }
1674   return 0;
1675 }
1676
1677 //=======================================================================
1678 //function : validrange
1679 //purpose  : 
1680 //=======================================================================
1681 static Standard_Integer validrange(Draw_Interpretor& di,
1682   Standard_Integer narg, const char** a)
1683 {
1684   if (narg < 2)
1685   {
1686     di << "usage: validrange edge [(out) u1 u2]";
1687     return 1;
1688   }
1689
1690   TopoDS_Edge aE = TopoDS::Edge(DBRep::Get(a[1],TopAbs_EDGE, true));
1691   if (aE.IsNull())
1692     return 1;
1693
1694   Standard_Real u1, u2;
1695   if (BRepLib::FindValidRange(aE, u1, u2))
1696   {
1697     if (narg > 3)
1698     {
1699       Draw::Set(a[2], u1);
1700       Draw::Set(a[3], u2);
1701     }
1702     else
1703     {
1704       di << u1 << " " << u2;
1705     }
1706   }
1707   else
1708     di << "edge has no valid range";
1709   return 0;
1710 }
1711
1712 //=======================================================================
1713 //function : CheckCommands
1714 //purpose  : 
1715 //=======================================================================
1716
1717 void BRepTest::CheckCommands(Draw_Interpretor& theCommands)
1718 {
1719   static Standard_Boolean done = Standard_False;
1720   if (done) return;
1721   done = Standard_True;
1722
1723   BRepTest_CheckCommands_SetFaultyName("faulty_");
1724   DBRep::BasicCommands(theCommands);
1725
1726   const char* g = "TOPOLOGY Check commands";
1727
1728 //  Modified by skv - Tue Apr 27 13:35:35 2004 Begin
1729   theCommands.Add("checkshape", 
1730                   "checkshape : no args to have help",
1731                   __FILE__,
1732                   checkshape,
1733                   g);
1734 //   theCommands.Add("checkshape", 
1735 //                "checks the validity of a shape : checkshape name,\n                      short description of check : checkshape name -short",
1736 //                __FILE__,
1737 //                CHK,
1738 //                g);
1739 //   theCommands.Add("checktopshape", 
1740 //                "checks the topological validity of a shape : checktopshape name",
1741 //                __FILE__,
1742 //                CHK,
1743 //                g);
1744 //  Modified by skv - Tue Apr 27 13:35:39 2004 End
1745
1746   theCommands.Add("checksection", 
1747                   "checks the closure of a section : checksection name [-r <RefVal>]\n"
1748                   "\"-r\" - allowed number of allone vertices.",
1749                   __FILE__,
1750                   checksection,
1751                   g);
1752
1753   theCommands.Add("checkdiff", 
1754                   "checks the validity of the diff beetween the shapes arg1..argn and result :\n checkdiff arg1 [arg2..argn] result [closedSolid (1/0)] [geomCtrl (1/0)]",
1755                   __FILE__,
1756                   checkdiff,
1757                   g);
1758
1759 g = "TOPOLOGY Analysis of shapes ";
1760
1761 theCommands.Add("shapeG0continuity",
1762                  "shapeG0continuity  shape  edge nbeval [epsnul [epsG0]]",
1763                   __FILE__,
1764                   shapeG0continuity, g);
1765
1766 theCommands.Add("shapeG1continuity",
1767                 "shapeG1continuity  shape  edge nbeval [epsnul [epsG0 [epsG1]]]",
1768                    __FILE__,
1769                 shapeG1continuity ,g);
1770 theCommands.Add("shapeG2continuity",
1771                   "shapeG2continuity shape  edge  nbeval [epsnul [epsG0 [epsG1 [maxlen [perce]]]]]",
1772                   __FILE__,
1773                   shapeG2continuity,g);
1774
1775 theCommands.Add("computetolerance",
1776                   "computetolerance shape",
1777                   __FILE__,
1778                   computetolerance,g);
1779
1780 theCommands.Add("clintedge",
1781                   "clintedge shape",
1782                   __FILE__,
1783                   clintedge,g);
1784
1785 theCommands.Add("facintedge",
1786                   "facintedge shape",
1787                   __FILE__,
1788                   facintedge,g);
1789
1790 theCommands.Add("fuseedge",
1791                   "fuseedge shape",
1792                   __FILE__,
1793                   fuseedge,g);
1794
1795 theCommands.Add("listfuseedge",
1796                   "listfuseedge shape",
1797                   __FILE__,
1798                   listfuseedge,g);
1799 theCommands.Add("tolsphere", "toolsphere shape\n"
1800                 "\t\tshows vertex tolerances by drawing spheres",
1801                 __FILE__, tolsphere, g);
1802 theCommands.Add("validrange",
1803                 "validrange edge [(out) u1 u2]\n"
1804                 "\t\tcomputes valid range of the edge, and\n"
1805                 "\t\tprints first and last values or sets the variables u1 and u2",
1806                 __FILE__, validrange, g);
1807 }
1808