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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
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>
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>
60 #include <TopOpeBRepTool_PurgeInternalEdges.hxx>
61 //#include <TopOpeBRepTool_FuseEdges.hxx>
62 #include <BRepLib.hxx>
63 #include <BRepLib_FuseEdges.hxx>
65 #include <TopTools_HSequenceOfShape.hxx>
66 #include <BRep_Builder.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TColStd_HArray1OfInteger.hxx>
70 #include <Standard_ErrorHandler.hxx>
71 #include <Standard_Failure.hxx>
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;
80 static char* checkfaultyname = NULL;
81 Standard_EXPORT void BRepTest_CheckCommands_SetFaultyName(const char* name)
83 if (checkfaultyname != NULL) {
84 free(checkfaultyname);
85 checkfaultyname = NULL;
88 checkfaultyname = (char*)malloc(strlen("faulty_")+1);
89 strcpy(checkfaultyname,"faulty_");
92 checkfaultyname = (char*)malloc(strlen(name)+1);
93 strcpy(checkfaultyname,name);
98 static TopTools_DataMapOfShapeListOfShape theMap;
99 static Standard_Integer nbfaulty = 0;
100 static Draw_SequenceOfDrawable3D lfaulty;
102 Standard_IMPORT Standard_Integer BRepCheck_Trace(const Standard_Integer phase);
104 //=======================================================================
105 //function : FindNamed
106 //=======================================================================
107 static Standard_Boolean FindNamed(const TopoDS_Shape& S,
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;
118 return Standard_False;
122 //=======================================================================
123 //function : Contains
124 //=======================================================================
125 static Standard_Boolean Contains(const TopTools_ListOfShape& L,
126 const TopoDS_Shape& S)
128 TopTools_ListIteratorOfListOfShape it;
129 for (it.Initialize(L); it.More(); it.Next()) {
130 if (it.Value().IsSame(S)) {
131 return Standard_True;
134 return Standard_False;
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)
149 BRepCheck_ListIteratorOfListOfStatus itl;
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)) {
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));
169 OS << "Shape " << Name << " ";
170 if (!FindNamed(S,Name)) {
172 Name = (char*)malloc(18*sizeof(char));
173 Sprintf(Name,"%s%d",checkfaultyname,nbfaulty);
175 lfaulty.Append(Draw::Get((Standard_CString&)Name));
177 OS << " on shape " << Name << " :\n";
178 for (;itl.More(); itl.Next()) {
179 BRepCheck::Print(itl.Value(),OS);
189 //=======================================================================
191 //=======================================================================
192 static void Print(Standard_OStream& OS,
193 const BRepCheck_Analyzer& Ana,
194 const TopoDS_Shape& S)
196 for (TopoDS_Iterator iter(S); iter.More(); iter.Next()) {
197 Print(OS,Ana,iter.Value());
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)) {
208 Name = (char*)malloc(18*sizeof(char));
209 Sprintf(Name,"%s%d",checkfaultyname,nbfaulty);
211 lfaulty.Append(Draw::Get((Standard_CString&)Name));
213 OS << "On Shape " << Name << " :\n";
215 for (;itl.More(); itl.Next()) {
216 if (itl.Value() != BRepCheck_NoError)
217 BRepCheck::Print(itl.Value(),OS);
221 if (!theMap.IsBound(S)) {
222 TopTools_ListOfShape thelist;
223 theMap.Bind(S, thelist);
228 PrintSub(OS,Ana,S,TopAbs_VERTEX);
231 PrintSub(OS,Ana,S,TopAbs_EDGE);
232 PrintSub(OS,Ana,S,TopAbs_VERTEX);
235 PrintSub(OS,Ana,S,TopAbs_WIRE);
236 PrintSub(OS,Ana,S,TopAbs_EDGE);
237 PrintSub(OS,Ana,S,TopAbs_VERTEX);
240 // PrintSub(OS,Ana,S,TopAbs_FACE);
243 // PrintSub(OS,Ana,S,TopAbs_EDGE);
244 PrintSub(OS,Ana,S,TopAbs_SHELL);
252 //=======================================================================
253 //function : computetolerance
255 //=======================================================================
256 static Standard_Integer computetolerance(Draw_Interpretor& di,
257 Standard_Integer narg, const char** a)
260 //std::cout << "Usage: computetolerance shape" << std::endl;
261 di << "Usage: computetolerance shape\n";
264 TopoDS_Shape S = DBRep::Get(a[1]);
266 if (S.ShapeType() == TopAbs_EDGE) {
267 BRepCheck_Edge bce(TopoDS::Edge(S));
269 //std::cout<< "Tolerance de " << (void*) &(*S.TShape()) << " : " << tol << std::endl;
270 Standard_SStream aSStream1;
271 aSStream1<< "Tolerance de " << (void*) &(*S.TShape()) << " : " << tol << "\n";
275 TopTools_MapOfShape theEdges;
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()));
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";
287 //std::cout << std::endl;
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)
301 di << a[0] << " shape [-r <ref_val>]\n";
305 Standard_Integer aCompareValue = -1;
306 TopoDS_Shape S = DBRep::Get(a[1]);
308 for (Standard_Integer anAI = 2; anAI < narg; anAI++)
310 if (!strcmp(a[anAI], "-r"))
312 aCompareValue = Draw::Atoi(a[++anAI]);
316 di << "Error: Wrong option" << a[anAI] << "\n";
320 TopTools_MapOfShape theVertices;
322 for (exp.Init(S, TopAbs_VERTEX); exp.More(); exp.Next()) {
323 if (!theVertices.Add(exp.Current()))
324 theVertices.Remove(exp.Current());
326 //std::cout << " nb alone Vertices : " << theVertices.Extent() << std::endl;
327 di << " nb alone Vertices : " << theVertices.Extent() << "\n";
329 if (aCompareValue >= 0)
331 if (theVertices.Extent() == aCompareValue)
333 di << "Section is OK\n";
337 di << "Error: "<< aCompareValue << " vertices are expected but " <<
338 theVertices.Extent() << " are found.\n";
343 Standard_Integer ipp=0;
344 TopTools_MapIteratorOfMapOfShape itvx;
345 for (itvx.Initialize(theVertices); itvx.More(); itvx.Next()) {
347 Sprintf(Name,"alone_%d",ipp);
348 DBRep::Set(Name, itvx.Key());
349 //std::cout << Name << " " ;
352 //std::cout << std::endl;
356 //=======================================================================
358 //=======================================================================
359 //function : checkdiff
360 //purpose : Checks the differences between a result and his arguments
361 //=======================================================================
362 static Standard_Integer checkdiff(Draw_Interpretor& di,
363 Standard_Integer narg, const char** a)
365 const char* syntaxe = "checkdiff arg1 [arg2..argn] result [closedSolid (0/1)] [geomCtrl (1/0)]";
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";
376 //std::cout << syntaxe << std::endl;
377 di << syntaxe << "\n";
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]);
387 //std::cout << syntaxe << std::endl;
388 di << syntaxe << "\n";
391 closedSolid = Draw::Atoi(a[narg-1]) != 0;
392 resu = DBRep::Get(a[narg-2]);
396 //std::cout << syntaxe << std::endl;
397 di << syntaxe << "\n";
400 geomCtrl=closedSolid;
401 closedSolid = Draw::Atoi(a[narg-2]) != 0;
402 resu = DBRep::Get(a[narg-3]);
405 //std::cout << syntaxe << std::endl;
406 di << syntaxe << "\n";
412 TopTools_ListOfShape lesArgs;
413 for (Standard_Integer id=1; id <=lastArg; id++) {
414 lesArgs.Append(DBRep::Get(a[id]));
417 if (BRepAlgo::IsValid(lesArgs, resu, closedSolid, geomCtrl)) {
418 //std::cout << "Difference is Valid." << std::endl;
419 di << "Difference is Valid.\n";
421 //std::cout << "error : Difference is Not Valid !" << std::endl;
422 di << "error : Difference is Not Valid !\n";
427 //=======================================================================
429 // Modified by skv - Tue Apr 27 13:38:44 2004 Begin
430 //=======================================================================
432 //purpose : Checks a shape
433 //=======================================================================
435 // static Standard_Integer CHK(Draw_Interpretor& theCommands,
436 // Standard_Integer narg, const char** a)
442 // Standard_Boolean doprint = Standard_True;
443 // if (narg == 3) { if (!strcmp(a[2],"-short")) doprint = Standard_False; }
445 // TopoDS_Shape S = DBRep::Get(a[1]);
447 // std::cout<<"not a topological shape"<<std::endl;
451 // Standard_Boolean GeomCtrl = Standard_True;
452 // if (!strcasecmp(a[0],"CHECKTOPSHAPE")) {
453 // GeomCtrl = Standard_False;
456 // BRepCheck_Analyzer ana(S,GeomCtrl);
457 // if (ana.IsValid()) {
458 // theCommands<<"This shape seems to be valid";
466 // Print(cout,ana,S);
470 // std::cout<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
471 // std::cout<<std::endl;
474 // theCommands<<"This shape has faulty shapes";
480 //=======================================================================
481 //function : ContextualDump
482 //purpose : Contextual (modeling) style of output.
483 //=======================================================================
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)
495 //Print(cout, theAna, theShape);
496 Standard_SStream aSStream;
497 Print(aSStream, theAna, theShape);
498 theCommands << aSStream;
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";
507 //std::cout<<std::endl;
512 //=======================================================================
513 //function : FillProblems
514 // purpose : auxilary for StructuralDump
515 //=======================================================================
516 static void FillProblems(const BRepCheck_Status stat,
517 Handle(TColStd_HArray1OfInteger)& NbProblems)
520 const Standard_Integer anID = static_cast<Standard_Integer> (stat);
522 if((NbProblems->Upper() < anID) || (NbProblems->Lower() > anID))
525 NbProblems->SetValue(anID, NbProblems->Value(anID)+1);
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)
540 BRepCheck_ListIteratorOfListOfStatus itl;
542 for (exp.Init(Shape,Subtype); exp.More(); exp.Next()) {
543 const Handle(BRepCheck_Result)& res = Ana.Result(exp.Current());
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());
554 if (itl.Value() != BRepCheck_NoError) {
555 Standard_Integer ii = 0;
557 for(ii=1; ii<=sl->Length(); ii++)
558 if(sl->Value(ii).IsSame(sub)) break;
560 if(ii>sl->Length()) {
562 FillProblems(itl.Value(),NbProblems);
564 for(ii=1; ii<=sl->Length(); ii++)
565 if(sl->Value(ii).IsSame(Shape)) break;
566 if(ii>sl->Length()) {
568 FillProblems(itl.Value(),NbProblems);
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)
587 for (TopoDS_Iterator iter(Shape); iter.More(); iter.Next()) {
588 GetProblemShapes(Ana,iter.Value(),sl, NbProblems);
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());
595 if (itl.Value() != BRepCheck_NoError) {
597 FillProblems(itl.Value(),NbProblems);
600 if (!theMap.IsBound(Shape)) {
601 TopTools_ListOfShape thelist;
602 theMap.Bind(Shape, thelist);
607 GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_VERTEX);
610 GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_WIRE);
611 GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_EDGE);
612 GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_VERTEX);
617 GetProblemSub(Ana, Shape, sl, NbProblems, TopAbs_SHELL);
625 //=======================================================================
626 //function : StructuralDump
627 //purpose : Structural (data exchange) style of output.
628 //=======================================================================
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)
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";
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();
655 GetProblemShapes(theAna, theShape, sl, NbProblems);
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";
662 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnCurveOnSurface);
663 if(NbProblems->Value(aProblemID)>0)
664 theCommands<<" Invalid Point on CurveOnSurface .......... "<<NbProblems->Value(aProblemID)<<"\n";
666 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPointOnSurface);
667 if(NbProblems->Value(aProblemID)>0)
668 theCommands<<" Invalid Point on Surface ................. "<<NbProblems->Value(aProblemID)<<"\n";
670 aProblemID = static_cast<Standard_Integer>(BRepCheck_No3DCurve);
671 if(NbProblems->Value(aProblemID)>0)
672 theCommands<<" No 3D Curve .............................. "<<NbProblems->Value(aProblemID)<<"\n";
674 aProblemID = static_cast<Standard_Integer>(BRepCheck_Multiple3DCurve);
675 if(NbProblems->Value(aProblemID)>0)
676 theCommands<<" Multiple 3D Curve ........................ "<<NbProblems->Value(aProblemID)<<"\n";
678 aProblemID = static_cast<Standard_Integer>(BRepCheck_Invalid3DCurve);
679 if(NbProblems->Value(aProblemID)>0)
680 theCommands<<" Invalid 3D Curve ......................... "<<NbProblems->Value(aProblemID)<<"\n";
682 aProblemID = static_cast<Standard_Integer>(BRepCheck_NoCurveOnSurface);
683 if(NbProblems->Value(aProblemID)>0)
684 theCommands<<" No Curve on Surface ...................... "<<NbProblems->Value(aProblemID)<<"\n";
686 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidCurveOnSurface);
687 if(NbProblems->Value(aProblemID)>0)
688 theCommands<<" Invalid Curve on Surface ................. "<<NbProblems->Value(aProblemID)<<"\n";
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";
694 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidSameRangeFlag);
695 if(NbProblems->Value(aProblemID)>0)
696 theCommands<<" Invalid SameRange Flag ................... "<<NbProblems->Value(aProblemID)<<"\n";
698 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidSameParameterFlag);
699 if(NbProblems->Value(aProblemID)>0)
700 theCommands<<" Invalid SameParameter Flag ............... "<<NbProblems->Value(aProblemID)<<"\n";
702 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidDegeneratedFlag);
703 if(NbProblems->Value(aProblemID)>0)
704 theCommands<<" Invalid Degenerated Flag ................. "<<NbProblems->Value(aProblemID)<<"\n";
706 aProblemID = static_cast<Standard_Integer>(BRepCheck_FreeEdge);
707 if(NbProblems->Value(aProblemID)>0)
708 theCommands<<" Free Edge ................................ "<<NbProblems->Value(aProblemID)<<"\n";
710 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidMultiConnexity);
711 if(NbProblems->Value(aProblemID)>0)
712 theCommands<<" Invalid MultiConnexity ................... "<<NbProblems->Value(aProblemID)<<"\n";
714 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidRange);
715 if(NbProblems->Value(aProblemID)>0)
716 theCommands<<" Invalid Range ............................ "<<NbProblems->Value(aProblemID)<<"\n";
718 aProblemID = static_cast<Standard_Integer>(BRepCheck_EmptyWire);
719 if(NbProblems->Value(aProblemID)>0)
720 theCommands<<" Empty Wire ............................... "<<NbProblems->Value(aProblemID)<<"\n";
722 aProblemID = static_cast<Standard_Integer>(BRepCheck_RedundantEdge);
723 if(NbProblems->Value(aProblemID)>0)
724 theCommands<<" Redundant Edge ........................... "<<NbProblems->Value(aProblemID)<<"\n";
726 aProblemID = static_cast<Standard_Integer>(BRepCheck_SelfIntersectingWire);
727 if(NbProblems->Value(aProblemID)>0)
728 theCommands<<" Self Intersecting Wire ................... "<<NbProblems->Value(aProblemID)<<"\n";
730 aProblemID = static_cast<Standard_Integer>(BRepCheck_NoSurface);
731 if(NbProblems->Value(aProblemID)>0)
732 theCommands<<" No Surface ............................... "<<NbProblems->Value(aProblemID)<<"\n";
734 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidWire);
735 if(NbProblems->Value(aProblemID)>0)
736 theCommands<<" Invalid Wire ............................. "<<NbProblems->Value(aProblemID)<<"\n";
738 aProblemID = static_cast<Standard_Integer>(BRepCheck_RedundantWire);
739 if(NbProblems->Value(aProblemID)>0)
740 theCommands<<" Redundant Wire ........................... "<<NbProblems->Value(aProblemID)<<"\n";
742 aProblemID = static_cast<Standard_Integer>(BRepCheck_IntersectingWires);
743 if(NbProblems->Value(aProblemID)>0)
744 theCommands<<" Intersecting Wires ....................... "<<NbProblems->Value(aProblemID)<<"\n";
746 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidImbricationOfWires);
747 if(NbProblems->Value(aProblemID)>0)
748 theCommands<<" Invalid Imbrication of Wires ............. "<<NbProblems->Value(aProblemID)<<"\n";
750 aProblemID = static_cast<Standard_Integer>(BRepCheck_EmptyShell);
751 if(NbProblems->Value(aProblemID)>0)
752 theCommands<<" Empty Shell .............................. "<<NbProblems->Value(aProblemID)<<"\n";
754 aProblemID = static_cast<Standard_Integer>(BRepCheck_RedundantFace);
755 if(NbProblems->Value(aProblemID)>0)
756 theCommands<<" Redundant Face ........................... "<<NbProblems->Value(aProblemID)<<"\n";
758 aProblemID = static_cast<Standard_Integer>(BRepCheck_UnorientableShape);
759 if(NbProblems->Value(aProblemID)>0)
760 theCommands<<" Unorientable Shape ....................... "<<NbProblems->Value(aProblemID)<<"\n";
762 aProblemID = static_cast<Standard_Integer>(BRepCheck_NotClosed);
763 if(NbProblems->Value(aProblemID)>0)
764 theCommands<<" Not Closed ............................... "<<NbProblems->Value(aProblemID)<<"\n";
766 aProblemID = static_cast<Standard_Integer>(BRepCheck_NotConnected);
767 if(NbProblems->Value(aProblemID)>0)
768 theCommands<<" Not Connected ............................ "<<NbProblems->Value(aProblemID)<<"\n";
770 aProblemID = static_cast<Standard_Integer>(BRepCheck_SubshapeNotInShape);
771 if(NbProblems->Value(aProblemID)>0)
772 theCommands<<" Subshape not in Shape .................... "<<NbProblems->Value(aProblemID)<<"\n";
774 aProblemID = static_cast<Standard_Integer>(BRepCheck_BadOrientation);
775 if(NbProblems->Value(aProblemID)>0)
776 theCommands<<" Bad Orientation .......................... "<<NbProblems->Value(aProblemID)<<"\n";
778 aProblemID = static_cast<Standard_Integer>(BRepCheck_BadOrientationOfSubshape);
779 if(NbProblems->Value(aProblemID)>0)
780 theCommands<<" Bad Orientation of Subshape .............. "<<NbProblems->Value(aProblemID)<<"\n";
782 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidToleranceValue);
783 if(NbProblems->Value(aProblemID)>0)
784 theCommands<<" Invalid tolerance value................... "<<NbProblems->Value(aProblemID)<<"\n";
786 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidPolygonOnTriangulation);
787 if(NbProblems->Value(aProblemID)>0)
788 theCommands<<" Invalid polygon on triangulation.......... "<<NbProblems->Value(aProblemID)<<"\n";
790 aProblemID = static_cast<Standard_Integer>(BRepCheck_InvalidImbricationOfShells);
791 if(NbProblems->Value(aProblemID)>0)
792 theCommands<<" Invalid Imbrication of Shells............. "<<NbProblems->Value(aProblemID)<<"\n";
794 aProblemID = static_cast<Standard_Integer>(BRepCheck_EnclosedRegion);
795 if(NbProblems->Value(aProblemID)>0)
796 theCommands<<" Enclosed Region........................... "<<NbProblems->Value(aProblemID)<<"\n";
798 aProblemID = static_cast<Standard_Integer>(BRepCheck_CheckFail);
799 if(NbProblems->Value(aProblemID)>0)
800 theCommands<<" checkshape failure........................ "<<NbProblems->Value(aProblemID)<<"\n";
804 theCommands<<" ------------------------------------------------\n";
805 theCommands<<"*** Shapes with problems : "<<sl->Length()<<"\n";
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();
814 for(i=1; i<=sl->Length(); i++) {
815 TopoDS_Shape shi = sl->Value(i);
816 TopAbs_ShapeEnum sti = shi.ShapeType();
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;
829 if(slv->Length()>0) {
830 TopoDS_Compound comp;
831 B.MakeCompound(comp);
832 Standard_Integer nb = slv->Length();
834 B.Add(comp,slv->Value(i));
836 Sprintf(aName,"%s_v",Pref);
837 DBRep::Set(aName,comp);
838 //std::cout<<"VERTEX : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
840 theCommands<<"VERTEX : "<<nb<<" Items -> compound named "<<aName<<"\n";
842 theCommands<<"VERTEX : "<<nb<<" Items -> compound named "<<aName<<"\n";
844 if(sle->Length()>0) {
845 TopoDS_Compound comp;
846 B.MakeCompound(comp);
847 Standard_Integer nb = sle->Length();
849 B.Add(comp,sle->Value(i));
851 Sprintf(aName,"%s_e",Pref);
852 DBRep::Set(aName,comp);
853 //std::cout<<"EDGE : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
855 theCommands<<"EDGE : "<<nb<<" Items -> compound named "<<aName<<"\n";
857 theCommands<<"EDGE : "<<nb<<" Items -> compound named "<<aName<<"\n";
859 if(slw->Length()>0) {
860 TopoDS_Compound comp;
861 B.MakeCompound(comp);
862 Standard_Integer nb = slw->Length();
864 B.Add(comp,slw->Value(i));
866 Sprintf(aName,"%s_w",Pref);
867 DBRep::Set(aName,comp);
868 //std::cout<<"WIRE : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
870 theCommands<<"WIRE : "<<nb<<" Items -> compound named "<<aName<<"\n";
872 theCommands<<"WIRE : "<<nb<<" Items -> compound named "<<aName<<"\n";
874 if(slf->Length()>0) {
875 TopoDS_Compound comp;
876 B.MakeCompound(comp);
877 Standard_Integer nb = slf->Length();
879 B.Add(comp,slf->Value(i));
881 Sprintf(aName,"%s_f",Pref);
882 DBRep::Set(aName,comp);
883 //std::cout<<"FACE : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
885 theCommands<<"FACE : "<<nb<<" Items -> compound named "<<aName<<"\n";
887 theCommands<<"FACE : "<<nb<<" Items -> compound named "<<aName<<"\n";
889 if(sls->Length()>0) {
890 TopoDS_Compound comp;
891 B.MakeCompound(comp);
892 Standard_Integer nb = sls->Length();
894 B.Add(comp,sls->Value(i));
896 Sprintf(aName,"%s_s",Pref);
897 DBRep::Set(aName,comp);
898 //std::cout<<"SHELL : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
900 theCommands<<"SHELL : "<<nb<<" Items -> compound named "<<aName<<"\n";
902 theCommands<<"SHELL : "<<nb<<" Items -> compound named "<<aName<<"\n";
904 if(slo->Length()>0) {
905 TopoDS_Compound comp;
906 B.MakeCompound(comp);
907 Standard_Integer nb = slo->Length();
909 B.Add(comp,slo->Value(i));
911 Sprintf(aName,"%s_o",Pref);
912 DBRep::Set(aName,comp);
913 //std::cout<<"SOLID : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
915 theCommands<<"SOLID : "<<nb<<" Items -> compound named "<<aName<<"\n";
917 theCommands<<"SOLID : "<<nb<<" Items -> compound named "<<aName<<"\n";
921 //=======================================================================
922 //function : checkshape
923 //purpose : Checks a shape
924 //=======================================================================
926 static Standard_Integer checkshape(Draw_Interpretor& theCommands,
927 Standard_Integer narg, const char** a)
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;
940 theCommands << "Usage : checkshape [-top] shape [result] [-short]\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";
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";
961 Standard_Boolean aGeomCtrl = Standard_True;
962 Standard_Integer aCurInd = 1;
964 if (!strcmp(a[1],"-top")) {
965 aGeomCtrl = Standard_False;
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";
978 Standard_CString aShapeName = a[aCurInd];
979 TopoDS_Shape aShape = DBRep::Get(aShapeName);
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";
988 Standard_Boolean IsShortDump = Standard_False;
989 Standard_Boolean IsContextDump = Standard_True;
990 Standard_Integer aBackInd = narg - 1;
992 if (aCurInd < aBackInd) {
993 if (!strcmp(a[aBackInd],"-short")) {
994 IsShortDump = Standard_True;
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";
1006 } else if (aCurInd < aBackInd) {
1007 IsContextDump = Standard_False;
1012 BRepCheck_Analyzer anAna(aShape,aGeomCtrl);
1013 Standard_Boolean isValid = anAna.IsValid();
1016 if (IsContextDump) {
1017 theCommands << "This shape seems to be valid";
1019 theCommands << " -- The Shape " << aShapeName << " looks OK";
1023 theCommands<<"This shape has faulty shapes";
1025 if (IsContextDump) {
1026 //ContextualDump(anAna, aShape);
1027 ContextualDump(theCommands, anAna, aShape);
1029 Standard_CString aPref = a[aCurInd+1];
1030 //StructuralDump(anAna, aShapeName, aPref, aShape);
1031 StructuralDump(theCommands, anAna, aShapeName, aPref, aShape);
1036 catch(Standard_Failure const& anException) {
1037 theCommands<<"checkshape exception : ";
1038 theCommands << anException.GetMessageString();
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 )
1060 static Standard_Integer shapeG1continuity (Draw_Interpretor& di, Standard_Integer n, const char** a)
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;
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);
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());
1084 face2=TopoDS::Face(It.Value());
1086 Standard_Boolean IsSeam = face1.IsEqual(face2);
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;
1095 const Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface
1096 (TopoDS::Edge(edge),face2,f2,l2);
1097 if (c2.IsNull()) return 1;
1099 Handle(Geom2d_Curve) curv1= new Geom2d_TrimmedCurve(c1,f1,l1);
1101 Handle(Geom2d_Curve) curv2= new Geom2d_TrimmedCurve(c2,f2,l2);
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;
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;
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;
1126 nbeval = (Standard_Integer ) Draw::Atof( a[3]);
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
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);
1150 deltaU = Abs(parf1- pard1)/nbeval;
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();
1158 {if (res.C0Value()>MaxG0Value) MaxG0Value = res.C0Value();
1159 if (res.G1Angle ()>MaxG1Angle) MaxG1Angle = res.G1Angle();}}
1160 else isconti = Standard_False;}
1162 else {LocalAnalysis_SurfaceContinuity res (curv1, curv2, (U+nb*deltaU ), surf1,surf2, GeomAbs_G1,epsnl,epsC0, epsC1, epsC2, epsG1,
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();;}
1171 else isconti = Standard_False;}
1172 if (!isconti) ISG1=Standard_False;
1176 while ((nb<nbeval)&& isdone );
1178 //if (!isdone) { std::cout<<" Problem in computation "<<std::endl; return 1;}
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;}
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";
1192 /*****************************************************************************/
1193 static Standard_Integer shapeG0continuity (Draw_Interpretor& di, Standard_Integer n, const char** a)
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 );
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);
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());
1218 face2=TopoDS::Face(It.Value());
1220 Standard_Boolean IsSeam = face1.IsEqual(face2);
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;
1229 const Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface
1230 (TopoDS::Edge(edge),face2,f2,l2);
1231 if (c2.IsNull()) return 1;
1233 Handle(Geom2d_Curve) curv1= new Geom2d_TrimmedCurve(c1,f1,l1);
1235 Handle(Geom2d_Curve) curv2= new Geom2d_TrimmedCurve(c2,f2,l2);
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;
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;
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;
1260 nbeval = (Standard_Integer ) Draw::Atof( a[3]);
1264 case 6 : epsC0 = Draw::Atof(a[5]);
1265 Standard_FALLTHROUGH
1266 case 5 : epsnl = Draw::Atof(a[4]);
1267 Standard_FALLTHROUGH
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);
1281 deltaU = Abs(parf1- pard1)/nbeval;
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( );
1289 if (res.C0Value()>MaxG0Value) MaxG0Value= res.C0Value();}
1290 else isconti = Standard_False;}
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();}
1298 else isconti = Standard_False;}
1301 if (!isconti) ISG0=Standard_False;
1304 while ((nb<nbeval)&& isdone );
1306 //f (!isdone) { std::cout<<" Problem in computation "<<std::endl; return 1;}
1308 // {std::cout<<" the continuity is G0 "<<std::endl;}
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;}
1314 {di<<" the continuity is G0 \n";}
1316 else { di<<" the continuity is not G0 \n";}
1317 di<<"MaxG0Value :"<< MaxG0Value << "\n";
1320 /*****************************************************************************************/
1321 static Standard_Integer shapeG2continuity (Draw_Interpretor& di, Standard_Integer n, const char** a)
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 );
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);
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());
1347 face2=TopoDS::Face(It.Value());
1349 Standard_Boolean IsSeam = face1.IsEqual(face2);
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;
1358 const Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface
1359 (TopoDS::Edge(edge),face2,f2,l2);
1360 if (c2.IsNull()) return 1;
1362 Handle(Geom2d_Curve) curv1= new Geom2d_TrimmedCurve(c1,f1,l1);
1364 Handle(Geom2d_Curve) curv2= new Geom2d_TrimmedCurve(c2,f2,l2);
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;
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;
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;
1389 nbeval = (Standard_Integer ) Draw::Atof( a[3]);
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
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);
1416 deltaU = Abs(parf1- pard1)/nbeval;
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();
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();
1429 else isconti = Standard_False;}
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;}
1446 if (!isconti) ISG2=Standard_False;
1449 while ((nb<nbeval)&& isdone );
1451 //if (!isdone) { std::cout<<" Problem in computation "<<std::endl; return 1;}
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;}
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";
1469 //=======================================================================
1470 //function : clintedge
1472 //=======================================================================
1473 static Standard_Integer clintedge(Draw_Interpretor& di,
1474 Standard_Integer narg, const char** a)
1479 //std::cout << "Usage: clintedge shape" << std::endl;
1480 di << "Usage: clintedge shape\n";
1483 TopoDS_Shape S = DBRep::Get(a[1]);
1485 TopTools_DataMapOfShapeListOfShape mymap;
1486 TopOpeBRepTool_PurgeInternalEdges mypurgealgo(S);
1487 Standard_Integer nbedges = mypurgealgo.NbEdges();
1490 //std::cout<<nbedges<<" internal (or external) edges to be removed"<<std::endl;
1491 di<<nbedges<<" internal (or external) edges to be removed\n";
1493 Standard_Integer i = 1;
1494 char* temp = newname;
1496 Sprintf(newname,"%s_%d",a[1],i);
1497 DBRep::Set(temp,mypurgealgo.Shape());
1498 //std::cout<<newname<<" ";
1501 //std::cout<<std::endl;
1505 di << "no internal (or external) edges\n";
1506 //std::cout << "no internal (or external) edges"<<std::endl;
1512 //=======================================================================
1513 //function : facintedge
1515 //=======================================================================
1516 static Standard_Integer facintedge(Draw_Interpretor& di,
1517 Standard_Integer narg, const char** a)
1522 //std::cout << "Usage: facintedge shape" << std::endl;
1523 di << "Usage: facintedge shape\n";
1526 TopoDS_Shape S = DBRep::Get(a[1]);
1528 TopTools_DataMapOfShapeListOfShape mymap;
1529 TopOpeBRepTool_PurgeInternalEdges mypurgealgo(S);
1530 mypurgealgo.Faces(mymap);
1532 Standard_Integer i = 1;
1533 char* temp = newname;
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<<" ";
1544 //std::cout<<std::endl;
1550 //=======================================================================
1551 //function : fuseedge
1553 //=======================================================================
1554 static Standard_Integer fuseedge(Draw_Interpretor& di,
1555 Standard_Integer narg, const char** a)
1560 //std::cout << "Usage: fuseedge shape" << std::endl;
1561 di << "Usage: fuseedge shape\n";
1564 TopoDS_Shape S = DBRep::Get(a[1]);
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();
1573 if (nbvertices > 0) {
1575 //std::cout<<nbvertices<<" vertices to be removed"<<std::endl;
1576 di<<nbvertices<<" vertices to be removed\n";
1578 Standard_Integer i = 1;
1579 char* temp = newname;
1581 Sprintf(newname,"%s_%d",a[1],i);
1582 DBRep::Set(temp,myfusealgo.Shape());
1583 //std::cout<<newname<<" ";
1586 //std::cout<<std::endl;
1590 di << "no vertices to remove\n";
1591 //std::cout << "no vertices to remove"<<std::endl;
1597 //=======================================================================
1598 //function : listfuseedge
1600 //=======================================================================
1601 static Standard_Integer listfuseedge(Draw_Interpretor& di,
1602 Standard_Integer narg, const char** a)
1607 //std::cout << "Usage: listfuseedge shape" << std::endl;
1608 di << "Usage: listfuseedge shape\n";
1611 TopoDS_Shape S = DBRep::Get(a[1]);
1613 TopTools_DataMapOfIntegerListOfShape mymap;
1614 BRepLib_FuseEdges myfusealgo(S);
1615 myfusealgo.Edges(mymap);
1618 char* temp = newname;
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;
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<<" ";
1636 //std::cout<<std::endl;
1642 //=======================================================================
1643 //function : tolsphere
1645 //=======================================================================
1646 static Standard_Integer tolsphere(Draw_Interpretor& di, Standard_Integer n, const char** a)
1650 di << "use toolsphere shape\n";
1654 TopoDS_Shape aS = DBRep::Get(a[1]);
1657 di << "No such shape " << a[1] << "\n";
1661 TopTools_IndexedMapOfShape aMapV;
1662 TopExp::MapShapes(aS, TopAbs_VERTEX, aMapV);
1663 for (Standard_Integer i = 1; i <= aMapV.Extent(); i++)
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);
1677 //=======================================================================
1678 //function : validrange
1680 //=======================================================================
1681 static Standard_Integer validrange(Draw_Interpretor& di,
1682 Standard_Integer narg, const char** a)
1686 di << "usage: validrange edge [(out) u1 u2]";
1690 TopoDS_Edge aE = TopoDS::Edge(DBRep::Get(a[1],TopAbs_EDGE, true));
1694 Standard_Real u1, u2;
1695 if (BRepLib::FindValidRange(aE, u1, u2))
1699 Draw::Set(a[2], u1);
1700 Draw::Set(a[3], u2);
1704 di << u1 << " " << u2;
1708 di << "edge has no valid range";
1712 //=======================================================================
1713 //function : CheckCommands
1715 //=======================================================================
1717 void BRepTest::CheckCommands(Draw_Interpretor& theCommands)
1719 static Standard_Boolean done = Standard_False;
1721 done = Standard_True;
1723 BRepTest_CheckCommands_SetFaultyName("faulty_");
1724 DBRep::BasicCommands(theCommands);
1726 const char* g = "TOPOLOGY Check commands";
1728 // Modified by skv - Tue Apr 27 13:35:35 2004 Begin
1729 theCommands.Add("checkshape",
1730 "checkshape : no args to have help",
1734 // theCommands.Add("checkshape",
1735 // "checks the validity of a shape : checkshape name,\n short description of check : checkshape name -short",
1739 // theCommands.Add("checktopshape",
1740 // "checks the topological validity of a shape : checktopshape name",
1744 // Modified by skv - Tue Apr 27 13:35:39 2004 End
1746 theCommands.Add("checksection",
1747 "checks the closure of a section : checksection name [-r <RefVal>]\n"
1748 "\"-r\" - allowed number of allone vertices.",
1753 theCommands.Add("checkdiff",
1754 "checks the validity of the diff between the shapes arg1..argn and result :\n checkdiff arg1 [arg2..argn] result [closedSolid (1/0)] [geomCtrl (1/0)]",
1759 g = "TOPOLOGY Analysis of shapes ";
1761 theCommands.Add("shapeG0continuity",
1762 "shapeG0continuity shape edge nbeval [epsnul [epsG0]]",
1764 shapeG0continuity, g);
1766 theCommands.Add("shapeG1continuity",
1767 "shapeG1continuity shape edge nbeval [epsnul [epsG0 [epsG1]]]",
1769 shapeG1continuity ,g);
1770 theCommands.Add("shapeG2continuity",
1771 "shapeG2continuity shape edge nbeval [epsnul [epsG0 [epsG1 [maxlen [perce]]]]]",
1773 shapeG2continuity,g);
1775 theCommands.Add("computetolerance",
1776 "computetolerance shape",
1778 computetolerance,g);
1780 theCommands.Add("clintedge",
1785 theCommands.Add("facintedge",
1790 theCommands.Add("fuseedge",
1795 theCommands.Add("listfuseedge",
1796 "listfuseedge shape",
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);