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