0025801: Some of the commands in BOPTest packages show the execution time without...
[occt.git] / src / BOPTest / BOPTest_CheckCommands.cxx
CommitLineData
b311480e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15#include <BOPTest.ixx>
7fd59977 16
63def8e6 17#include <vector>
18#include <algorithm>
19#include <functional>
20
21#include <TCollection_AsciiString.hxx>
7fd59977 22
e98e3990 23#include <TopExp_Explorer.hxx>
24
25#include <TopTools_MapOfShape.hxx>
26#include <TopTools_ShapeMapHasher.hxx>
27
7fd59977 28#include <TopoDS_Shape.hxx>
29#include <TopoDS_Compound.hxx>
30#include <BRep_Builder.hxx>
63def8e6 31#include <BRepBuilderAPI_Copy.hxx>
7fd59977 32
7fd59977 33#include <DBRep.hxx>
4e57c75e 34#include <Draw.hxx>
80db5701 35
36#include <BOPCol_ListOfShape.hxx>
37
38#include <BOPDS_DS.hxx>
63def8e6 39#include <BOPDS_MapOfPassKey.hxx>
80db5701 40
4e57c75e 41#include <BOPAlgo_CheckerSI.hxx>
4e57c75e 42#include <BOPAlgo_ArgumentAnalyzer.hxx>
43#include <BOPAlgo_CheckResult.hxx>
e98e3990 44#include <BOPTools_AlgoTools.hxx>
45
c7b59798 46#include <OSD_Timer.hxx>
43cb0011 47#include <BOPTest_Objects.hxx>
48
63def8e6 49//
7fd59977 50static
63def8e6 51 void MakeShapeForFullOutput (const TCollection_AsciiString&,
52 const Standard_Integer,
53 const BOPCol_ListOfShape&,
54 Standard_Integer& ,
e98e3990 55 Draw_Interpretor&,
56 Standard_Boolean bCurveOnSurf = Standard_False,
57 Standard_Real aMaxDist = 0.,
58 Standard_Real aMaxParameter = 0.);
7fd59977 59//
63def8e6 60static Standard_Integer bopcheck (Draw_Interpretor&, Standard_Integer, const char** );
61static Standard_Integer bopargcheck(Draw_Interpretor&, Standard_Integer, const char** );
e98e3990 62static Standard_Integer xdistef(Draw_Interpretor&, Standard_Integer, const char** );
63static Standard_Integer checkcurveonsurf (Draw_Interpretor&, Standard_Integer, const char**);
7fd59977 64
65//=======================================================================
66//function : CheckCommands
67//purpose :
68//=======================================================================
63def8e6 69void BOPTest::CheckCommands(Draw_Interpretor& theCommands)
7fd59977 70{
71 static Standard_Boolean done = Standard_False;
72 if (done)
73 return;
74
75 done = Standard_True;
76 // Chapter's name
43cb0011 77 const char* g = "BOPTest commands";
7fd59977 78 //
6f31882a 79 theCommands.Add("bopcheck",
43cb0011 80 "use bopcheck Shape [level of check: 0 - 9] [-t]",
6f31882a 81 __FILE__, bopcheck, g);
82 theCommands.Add("bopargcheck" ,
43cb0011 83 "use bopargcheck without parameters to get ",
6f31882a 84 __FILE__, bopargcheck, g);
e98e3990 85 theCommands.Add ("xdistef" ,
43cb0011 86 "use xdistef edge face",
e98e3990 87 __FILE__, xdistef, g);
88 theCommands.Add("checkcurveonsurf",
43cb0011 89 "use checkcurveonsurf shape",
e98e3990 90 __FILE__, checkcurveonsurf, g);
7fd59977 91}
63def8e6 92//=======================================================================
93//class : BOPTest_Interf
94//purpose : Auxiliary class
95//=======================================================================
96class BOPTest_Interf {
97 public:
98 BOPTest_Interf() : myIndex1(-1), myIndex2(-1), myType(-1) {
99 }
100 //
101 ~BOPTest_Interf() {
102 }
103 //
104 void SetIndices(const Standard_Integer theIndex1,
105 const Standard_Integer theIndex2) {
106 myIndex1=theIndex1;
107 myIndex2=theIndex2;
108 }
109 //
110 void Indices(Standard_Integer& theIndex1,
111 Standard_Integer& theIndex2) const {
112 theIndex1=myIndex1;
113 theIndex2=myIndex2;
114 }
115 //
116 void SetType(const Standard_Integer theType) {
117 myType=theType;
118 }
119 //
120 Standard_Integer Type() const {
121 return myType;
122 }
123 //
124 bool operator < (const BOPTest_Interf& aOther) const {
125 bool bFlag;
126 //
127 if (myType==aOther.myType) {
128 if (myIndex1 == aOther.myIndex1) {
129 bFlag=(myIndex2 < aOther.myIndex2);
130 }
131 else {
132 bFlag=(myIndex1 < aOther.myIndex1);
133 }
134 }
135 else {
136 bFlag=(myType < aOther.myType);
137 }
138 //
139 return bFlag;
140 }
141 //
142 protected:
143 Standard_Integer myIndex1;
144 Standard_Integer myIndex2;
145 Standard_Integer myType;
146};
7fd59977 147//=======================================================================
148//function : bopcheck
149//purpose :
150//=======================================================================
63def8e6 151Standard_Integer bopcheck (Draw_Interpretor& di,
152 Standard_Integer n,
153 const char** a )
7fd59977 154{
7fd59977 155 if (n<2) {
43cb0011 156 di << " use bopcheck Shape [level of check: 0 - 9] [-t]\n";
6f31882a 157 di << " The level of check defines ";
80db5701 158 di << " which interferences will be checked:\n";
159 di << " 0 - V/V only\n";
160 di << " 1 - V/V, V/E\n";
161 di << " 2 - V/V, V/E, E/E\n";
162 di << " 3 - V/V, V/E, E/E , V/F\n";
163 di << " 4 - V/V, V/E, E/E, V/F , E/F\n";
164 di << " 5 - V/V, V/E, E/E, V/F, E/F, F/F;\n";
165 di << " 6 - V/V, V/E, E/E, V/F, E/F, F/F, V/Z\n";
166 di << " 7 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z\n";
167 di << " 8 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z, F/Z\n";
168 di << " 9 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z, F/Z, Z/Z\n";
169 di << " Default level is 9\n";
7fd59977 170 return 1;
171 }
80db5701 172 //
173 TopoDS_Shape aS = DBRep::Get(a[1]);
174 if (aS.IsNull()) {
4e57c75e 175 di << "null shapes are not allowed here!";
176 return 1;
177 }
7fd59977 178 //
63def8e6 179 Standard_Boolean bRunParallel, bShowTime;
180 Standard_Integer i, aLevel, aNbInterfTypes;
43cb0011 181 Standard_Real aTol;
80db5701 182 //
183 aNbInterfTypes=BOPDS_DS::NbInterfTypes();
184 //
63def8e6 185 aLevel=aNbInterfTypes-1;
186 //
187 if (n>2) {
b1d15f53 188 if (a[2][0] != '-') {
189 aLevel=Draw::Atoi(a[2]);
190 }
63def8e6 191 }
192 //
193 if (aLevel < 0 || aLevel > aNbInterfTypes-1) {
80db5701 194 di << "Invalid level";
195 return 1;
196 }
63def8e6 197 //
198 bShowTime=Standard_False;
43cb0011 199 aTol=BOPTest_Objects::FuzzyValue();
200 bRunParallel=BOPTest_Objects::RunParallel();
201 //
b1d15f53 202 for (i=2; i<n; ++i) {
43cb0011 203 if (!strcmp(a[i], "-t")) {
63def8e6 204 bShowTime=Standard_True;
205 }
c7b59798 206 }
63def8e6 207 //
208 //aLevel = (n==3) ? Draw::Atoi(a[2]) : aNbInterfTypes-1;
80db5701 209 //-------------------------------------------------------------------
63def8e6 210 char buf[256], aName1[32], aName2[32];
211 char aInterfTypes[10][4] = {
80db5701 212 "V/V", "V/E", "E/E","V/F", "E/F", "F/F", "V/Z", "E/Z", "F/Z", "Z/Z"
213 };
80db5701 214 //
63def8e6 215 Standard_Integer iErr, iCnt, n1, n2, iT;
216 TopAbs_ShapeEnum aType1, aType2;
217 BOPAlgo_CheckerSI aChecker;
218 BOPCol_ListOfShape aLS;
219 BOPDS_MapIteratorMapOfPassKey aItMPK;
63def8e6 220 //
221 if (aLevel < (aNbInterfTypes-1)) {
6f31882a 222 di << "Info:\nThe level of check is set to "
63def8e6 223 << aInterfTypes[aLevel] << ", i.e. intersection(s)\n";
224
225 for (i=aLevel+1; i<aNbInterfTypes; ++i) {
226 di << aInterfTypes[i];
80db5701 227 if (i<aNbInterfTypes-1) {
c1fe53c6 228 di << ", ";
229 }
230 }
231 di << " will not be checked.\n\n";
232 }
80db5701 233 //
63def8e6 234 aLS.Append(aS);
235 aChecker.SetArguments(aLS);
236 aChecker.SetLevelOfCheck(aLevel);
237 aChecker.SetRunParallel(bRunParallel);
43cb0011 238 aChecker.SetFuzzyValue(aTol);
80db5701 239 //
c7b59798 240 OSD_Timer aTimer;
241 aTimer.Start();
4e57c75e 242 //
243 aChecker.Perform();
4e57c75e 244 //
c7b59798 245 aTimer.Stop();
4e57c75e 246 //
63def8e6 247 iErr=aChecker.ErrorStatus();
4e57c75e 248 //
63def8e6 249 const BOPDS_DS& aDS=*(aChecker.PDS());
250 //
251 const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
252 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
253 using namespace std;
254 vector <BOPTest_Interf> aVec;
255 vector <BOPTest_Interf>::iterator aIt;
256 BOPTest_Interf aBInterf;
257 //
258 aItMPK.Initialize(aMPK);
259 for (; aItMPK.More(); aItMPK.Next()) {
260 const BOPDS_PassKey& aPK=aItMPK.Value();
261 aPK.Ids(n1, n2);
262 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
263 continue;
264 }
265 //
266 const BOPDS_ShapeInfo& aSI1=aDS.ShapeInfo(n1);
267 const BOPDS_ShapeInfo& aSI2=aDS.ShapeInfo(n2);
268 aType1=aSI1.ShapeType();
269 aType2=aSI2.ShapeType();
270 //
271 iT=BOPDS_Tools::TypeToInteger(aType1, aType2);
272 //
273 aBInterf.SetIndices(n1, n2);
274 aBInterf.SetType(iT);
275 //
276 aVec.push_back(aBInterf);
277 }
278 //
279 sort( aVec.begin(), aVec.end(), less<BOPTest_Interf>());
280 //
281 iCnt=0;
282 for (aIt=aVec.begin(); aIt!=aVec.end(); aIt++) {
283 const BOPTest_Interf& aBI=*aIt;
284 //
285 aBI.Indices(n1, n2);
286 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
287 continue;
7fd59977 288 }
63def8e6 289 //
290 const TopoDS_Shape& aS1=aDS.Shape(n1);
291 const TopoDS_Shape& aS2=aDS.Shape(n2);
292 //
293 iT=aBI.Type();
294 di << aInterfTypes[iT] << ": ";
295 //
296 sprintf(aName1, "x%d", n1);
297 //sprintf(aName1, "x%d", iCnt);
298 DBRep::Set (aName1, aS1);
299 //
300 ++iCnt;
301 sprintf(aName2, "x%d", n2);
302 //sprintf(aName2, "x%d", iCnt);
303 DBRep::Set (aName2, aS2);
304 ++iCnt;
305 //
306 sprintf(buf, "%s %s \n", aName1, aName2);
307 di << buf;
7fd59977 308 }
6f31882a 309 //
4e57c75e 310 if (iErr) {
6f31882a 311 di << "There were errors during the operation, ";
312 di << "so the list may be incomplete." << "\n";
4e57c75e 313 }
6f31882a 314 //
63def8e6 315 if (!iCnt) {
7fd59977 316 di << " This shape seems to be OK." << "\n";
317 }
c7b59798 318 if (bShowTime)
319 {
320 Sprintf(buf, " Tps: %7.2lf\n", aTimer.ElapsedTime());
63def8e6 321 di << buf;
7fd59977 322 }
63def8e6 323 return 0;
7fd59977 324}
6f31882a 325//=======================================================================
326//function : bopargcheck
327//purpose :
328//=======================================================================
e98e3990 329Standard_Integer bopargcheck (Draw_Interpretor& di,
330 Standard_Integer n,
63def8e6 331 const char** a )
7fd59977 332{
333 if (n<2) {
334 di << "\n";
6f31882a 335 di << " Use >bopargcheck Shape1 [[Shape2] ";
43cb0011 336 di << "[-F/O/C/T/S/U] [/R|F|T|V|E|I|P|C|S]] [#BF]\n\n";
7fd59977 337 di << " -<Boolean Operation>" << "\n";
338 di << " F (fuse)" << "\n";
339 di << " O (common)" << "\n";
340 di << " C (cut)" << "\n";
341 di << " T (cut21)" << "\n";
342 di << " S (section)" << "\n";
343 di << " U (unknown)" << "\n";
6f31882a 344 di << " For example: \"bopargcheck s1 s2 -F\" enables" ;
63def8e6 345 di << " checking for Fuse operation" << "\n";
7fd59977 346 di << " default - section" << "\n" << "\n";
7fd59977 347 di << " /<Test Options>" << "\n";
7fd59977 348 di << " R (disable small edges (shrank range) test)" << "\n";
7fd59977 349 di << " F (disable faces verification test)" << "\n";
7fd59977 350 di << " T (disable tangent faces searching test)" << "\n";
7fd59977 351 di << " V (disable test possibility to merge vertices)" << "\n";
7fd59977 352 di << " E (disable test possibility to merge edges)" << "\n";
353 di << " I (disable self-interference test)" << "\n";
354 di << " P (disable shape type test)" << "\n";
0e09ee8e 355 di << " C (disable test for shape continuity)" << "\n";
e98e3990 356 di << " S (disable curve on surface check)" << "\n";
6f31882a 357 di << " For example: \"bopargcheck s1 s2 /RI\" disables ";
358 di << "small edge detection and self-intersection detection" << "\n";
7fd59977 359 di << " default - all options are enabled" << "\n" << "\n";
360 di << " #<Additional Test Options>" << "\n";
361 di << " B (stop test on first faulty found); default OFF" << "\n";
6f31882a 362 di << " F (full output for faulty shapes); default - output ";
363 di << "in a short format" << "\n" << "\n";
364 di << " NOTE: <Boolean Operation> and <Test Options> are ";
365 di << "used only for couple" << "\n";
366 di << " of argument shapes, except I and P options ";
367 di << "that are always used for" << "\n";
368 di << " couple of shapes as well as for ";
369 di <<"single shape test." << "\n";
7fd59977 370 return 1;
371 }
372
6f31882a 373 TopoDS_Shape aS1 = DBRep::Get(a[1]);
7fd59977 374
6f31882a 375 if(aS1.IsNull()) {
7fd59977 376 di << "Error: null shape not allowed!" << "\n";
6f31882a 377 di << "Type bopargcheck without arguments for more ";
378 di <<"information" << "\n";
7fd59977 379 return 1;
380 }
381
382 Standard_Boolean isBO = Standard_False;
383 Standard_Integer indxBO = 0;
384 Standard_Boolean isOP = Standard_False;
385 Standard_Integer indxOP = 0;
386 Standard_Boolean isAD = Standard_False;
387 Standard_Integer indxAD = 0;
388 Standard_Boolean isS2 = Standard_False;
389 Standard_Integer indxS2 = 0;
b1d15f53 390 Standard_Real aTolerance = 0;
7fd59977 391
43cb0011 392 aTolerance=BOPTest_Objects::FuzzyValue();
393
7fd59977 394 if(n >= 3) {
395 Standard_Integer iIndex = 0;
396 for(iIndex = 2; iIndex < n; iIndex++) {
43cb0011 397 if(a[iIndex][0] == '-') {
7fd59977 398 isBO = Standard_True;
399 indxBO = iIndex;
400 }
43cb0011 401 else if(a[iIndex][0] == '/') {
7fd59977 402 isOP = Standard_True;
403 indxOP = iIndex;
404 }
43cb0011 405 else if(a[iIndex][0] == '#') {
7fd59977 406 isAD = Standard_True;
407 indxAD = iIndex;
408 }
409 else {
410 isS2 = Standard_True;
411 indxS2 = iIndex;
412 }
413 }
414 }
b1d15f53 415
7fd59977 416 // set & test second shape
4e57c75e 417 TopoDS_Shape aS22, aS2;
7fd59977 418 if(isS2) {
419 if(indxS2 != 2) {
420 di << "Error: second shape should follow the first one!" << "\n";
421 di << "Type bopargcheck without arguments for more information" << "\n";
422 return 1;
423 }
424 else {
4e57c75e 425 aS22 = DBRep::Get(a[2]);
426 if(aS22.IsNull()) {
7fd59977 427 di << "Error: second shape is null!" << "\n";
428 di << "Type bopargcheck without arguments for more information" << "\n";
429 return 1;
430 }
431 }
432 }
b1d15f53 433
7fd59977 434 // init checker
4e57c75e 435 BOPAlgo_ArgumentAnalyzer aChecker;
b1d15f53 436 aChecker.SetFuzzyValue(aTolerance);
7fd59977 437 aChecker.SetShape1(aS1);
438
439 // set default options (always tested!) for single and couple shapes
e98e3990 440 aChecker.ArgumentTypeMode() = Standard_True;
441 aChecker.SelfInterMode() = Standard_True;
442 aChecker.SmallEdgeMode() = Standard_True;
443 aChecker.RebuildFaceMode() = Standard_True;
444 aChecker.ContinuityMode() = Standard_True;
445 aChecker.CurveOnSurfaceMode() = Standard_True;
7fd59977 446
447 // test & set options and operation for two shapes
4e57c75e 448 if(!aS22.IsNull()) {
449 aS2 = BRepBuilderAPI_Copy(aS22).Shape();
7fd59977 450 aChecker.SetShape2(aS2);
451 // set operation (default - Section)
452 if(isBO) {
453 if(a[indxBO][1] == 'F' || a[indxBO][1] == 'f') {
4e57c75e 454 aChecker.OperationType() = BOPAlgo_FUSE;
7fd59977 455 }
456 else if(a[indxBO][1] == 'O' || a[indxBO][1] == 'o') {
4e57c75e 457 aChecker.OperationType() = BOPAlgo_COMMON;
7fd59977 458 }
459 else if(a[indxBO][1] == 'C' || a[indxBO][1] == 'c') {
4e57c75e 460 aChecker.OperationType() = BOPAlgo_CUT;
7fd59977 461 }
462 else if(a[indxBO][1] == 'T' || a[indxBO][1] == 't') {
4e57c75e 463 aChecker.OperationType() = BOPAlgo_CUT21;
7fd59977 464 }
465 else if(a[indxBO][1] == 'S' || a[indxBO][1] == 's') {
4e57c75e 466 aChecker.OperationType() = BOPAlgo_SECTION;
7fd59977 467 }
468 else if(a[indxBO][1] == 'U' || a[indxBO][1] == 'u') {
4e57c75e 469 aChecker.OperationType() = BOPAlgo_UNKNOWN;
7fd59977 470 }
471 else {
472 di << "Error: invalid boolean operation type!" << "\n";
473 di << "Type bopargcheck without arguments for more information" << "\n";
474 return 1;
475 }
476 }
477 else
4e57c75e 478 aChecker.OperationType() = BOPAlgo_SECTION;
7fd59977 479
7fd59977 480 aChecker.TangentMode() = Standard_True;
481 aChecker.MergeVertexMode() = Standard_True;
482 aChecker.MergeEdgeMode() = Standard_True;
7fd59977 483 }
0e09ee8e 484
485 // set options (default - all ON)
486 if(isOP) {
487 Standard_Integer ind = 1;
488 while(a[indxOP][ind] != 0) {
489 if(a[indxOP][ind] == 'R' || a[indxOP][ind] == 'r') {
490 aChecker.SmallEdgeMode() = Standard_False;
491 }
492 else if(a[indxOP][ind] == 'F' || a[indxOP][ind] == 'f') {
493 aChecker.RebuildFaceMode() = Standard_False;
494 }
495 else if(a[indxOP][ind] == 'T' || a[indxOP][ind] == 't') {
496 aChecker.TangentMode() = Standard_False;
7fd59977 497 }
0e09ee8e 498 else if(a[indxOP][ind] == 'V' || a[indxOP][ind] == 'v') {
499 aChecker.MergeVertexMode() = Standard_False;
500 }
501 else if(a[indxOP][ind] == 'E' || a[indxOP][ind] == 'e') {
502 aChecker.MergeEdgeMode() = Standard_False;
503 }
504 else if(a[indxOP][ind] == 'I' || a[indxOP][ind] == 'i') {
505 aChecker.SelfInterMode() = Standard_False;
506 }
507 else if(a[indxOP][ind] == 'P' || a[indxOP][ind] == 'p') {
508 aChecker.ArgumentTypeMode() = Standard_False;
509 }
510 else if(a[indxOP][ind] == 'C' || a[indxOP][ind] == 'c') {
511 aChecker.ContinuityMode() = Standard_False;
512 }
e98e3990 513 else if(a[indxOP][ind] == 'S' || a[indxOP][ind] == 's') {
514 aChecker.CurveOnSurfaceMode() = Standard_False;
515 }
0e09ee8e 516 else {
517 di << "Error: invalid test option(s)!" << "\n";
518 di << "Type bopargcheck without arguments for more information" << "\n";
519 return 1;
520 }
521 ind++;
7fd59977 522 }
523 }
524
525 // set additional options
526 Standard_Boolean fullOutput = Standard_False;
527 if(isAD) {
528 Standard_Integer ind = 1;
529 while(a[indxAD][ind] != 0) {
530 if(a[indxAD][ind] == 'B' || a[indxAD][ind] == 'b') {
531 aChecker.StopOnFirstFaulty() = Standard_True;
532 }
533 else if(a[indxAD][ind] == 'F' || a[indxAD][ind] == 'f') {
534 fullOutput = Standard_True;
535 }
536 else {
537 di << "Error: invalid additional test option(s)!" << "\n";
538 di << "Type bopargcheck without arguments for more information" << "\n";
539 return 1;
540 }
541 ind++;
542 }
543 }
544
545 // run checker
546 aChecker.Perform();
547
548 // process result of checking
549 if(!aChecker.HasFaulty()) {
550 di << "Shape(s) seem(s) to be valid for BOP." << "\n";
551 }
552 else {
553 if(!fullOutput) {
554 di << "Faulties, that can not be treated by BOP, are detected." << "\n";
555 }
556 else {
4e57c75e 557 const BOPAlgo_ListOfCheckResult& aResultList = aChecker.GetCheckResult();
558 BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResultList);
7fd59977 559
560 Standard_Integer S1_BadType = 0, S1_SelfInt = 0, S1_SmalE = 0, S1_BadF = 0, S1_BadV = 0, S1_BadE = 0;
561 Standard_Integer S1_SelfIntAll = 0, S1_SmalEAll = 0, S1_BadFAll = 0, S1_BadVAll = 0, S1_BadEAll = 0;
562 Standard_Integer S2_BadType = 0, S2_SelfInt = 0, S2_SmalE = 0, S2_BadF = 0, S2_BadV = 0, S2_BadE = 0;
563 Standard_Integer S2_SelfIntAll = 0, S2_SmalEAll = 0, S2_BadFAll = 0, S2_BadVAll = 0, S2_BadEAll = 0;
4e57c75e 564 Standard_Integer S1_OpAb = 0, S2_OpAb = 0;
0e09ee8e 565 Standard_Integer S1_C0 = 0, S2_C0 = 0, S1_C0All = 0, S2_C0All = 0;
e98e3990 566 Standard_Integer S1_COnS = 0, S2_COnS = 0, S1_COnSAll = 0, S2_COnSAll = 0;
7fd59977 567 Standard_Boolean hasUnknown = Standard_False;
568
569 TCollection_AsciiString aS1SIBaseName("s1si_");
570 TCollection_AsciiString aS1SEBaseName("s1se_");
571 TCollection_AsciiString aS1BFBaseName("s1bf_");
572 TCollection_AsciiString aS1BVBaseName("s1bv_");
573 TCollection_AsciiString aS1BEBaseName("s1be_");
0e09ee8e 574 TCollection_AsciiString aS1C0BaseName("s1C0_");
e98e3990 575 TCollection_AsciiString aS1COnSBaseName("s1COnS_");
7fd59977 576 TCollection_AsciiString aS2SIBaseName("s2si_");
577 TCollection_AsciiString aS2SEBaseName("s2se_");
578 TCollection_AsciiString aS2BFBaseName("s2bf_");
579 TCollection_AsciiString aS2BVBaseName("s2bv_");
580 TCollection_AsciiString aS2BEBaseName("s2be_");
0e09ee8e 581 TCollection_AsciiString aS2C0BaseName("s2C0_");
e98e3990 582 TCollection_AsciiString aS2COnSBaseName("s2COnS_");
7fd59977 583
584 for(; anIt.More(); anIt.Next()) {
4e57c75e 585 const BOPAlgo_CheckResult& aResult = anIt.Value();
7fd59977 586 const TopoDS_Shape & aSS1 = aResult.GetShape1();
587 const TopoDS_Shape & aSS2 = aResult.GetShape2();
4e57c75e 588 const BOPCol_ListOfShape & aLS1 = aResult.GetFaultyShapes1();
589 const BOPCol_ListOfShape & aLS2 = aResult.GetFaultyShapes2();
7fd59977 590 Standard_Boolean isL1 = !aLS1.IsEmpty();
591 Standard_Boolean isL2 = !aLS2.IsEmpty();
592
593 switch(aResult.GetCheckStatus()) {
4e57c75e 594 case BOPAlgo_BadType: {
7fd59977 595 if(!aSS1.IsNull()) S1_BadType++;
596 if(!aSS2.IsNull()) S2_BadType++;
597 }
4e57c75e 598 break;
599 case BOPAlgo_SelfIntersect: {
7fd59977 600 if(!aSS1.IsNull()) {
601 S1_SelfInt++;
602 if(isL1)
603 MakeShapeForFullOutput(aS1SIBaseName, S1_SelfInt, aLS1, S1_SelfIntAll, di);
604 }
605 if(!aSS2.IsNull()) {
606 S2_SelfInt++;
607 if(isL2)
608 MakeShapeForFullOutput(aS2SIBaseName, S2_SelfInt, aLS2, S2_SelfIntAll, di);
609 }
610 }
4e57c75e 611 break;
612 case BOPAlgo_TooSmallEdge: {
7fd59977 613 if(!aSS1.IsNull()) {
614 S1_SmalE++;
615 if(isL1)
616 MakeShapeForFullOutput(aS1SEBaseName, S1_SmalE, aLS1, S1_SmalEAll, di);
617 }
618 if(!aSS2.IsNull()) {
619 S2_SmalE++;
620 if(isL2)
621 MakeShapeForFullOutput(aS2SEBaseName, S2_SmalE, aLS2, S2_SmalEAll, di);
622 }
623 }
4e57c75e 624 break;
625 case BOPAlgo_NonRecoverableFace: {
7fd59977 626 if(!aSS1.IsNull()) {
627 S1_BadF++;
628 if(isL1)
629 MakeShapeForFullOutput(aS1BFBaseName, S1_BadF, aLS1, S1_BadFAll, di);
630 }
631 if(!aSS2.IsNull()) {
632 S2_BadF++;
633 if(isL2)
634 MakeShapeForFullOutput(aS2BFBaseName, S2_BadF, aLS2, S2_BadFAll, di);
635 }
636 }
4e57c75e 637 break;
638 case BOPAlgo_IncompatibilityOfVertex: {
7fd59977 639 if(!aSS1.IsNull()) {
640 S1_BadV++;
641 if(isL1) {
642 MakeShapeForFullOutput(aS1BVBaseName, S1_BadV, aLS1, S1_BadVAll, di);
4e57c75e 643 }
7fd59977 644 }
645 if(!aSS2.IsNull()) {
646 S2_BadV++;
647 if(isL2){
648 MakeShapeForFullOutput(aS2BVBaseName, S2_BadV, aLS2, S2_BadVAll, di);
4e57c75e 649 }
7fd59977 650 }
651 }
4e57c75e 652 break;
653 case BOPAlgo_IncompatibilityOfEdge: {
7fd59977 654 if(!aSS1.IsNull()) {
655 S1_BadE++;
656 if(isL1) {
657 MakeShapeForFullOutput(aS1BEBaseName, S1_BadE, aLS1, S1_BadEAll, di);
4e57c75e 658 }
7fd59977 659 }
660 if(!aSS2.IsNull()) {
661 S2_BadE++;
662 if(isL2) {
663 MakeShapeForFullOutput(aS2BEBaseName, S2_BadE, aLS2, S2_BadEAll, di);
4e57c75e 664 }
7fd59977 665 }
666 }
4e57c75e 667 break;
668 case BOPAlgo_IncompatibilityOfFace: {
7fd59977 669 // not yet implemented
670 }
4e57c75e 671 break;
0e09ee8e 672 case BOPAlgo_GeomAbs_C0: {
673 if(!aSS1.IsNull()) {
674 S1_C0++;
675 if(isL1) {
676 MakeShapeForFullOutput(aS1C0BaseName, S1_C0, aLS1, S1_C0All, di);
677 }
678 }
679 if(!aSS2.IsNull()) {
680 S2_C0++;
681 if(isL2) {
682 MakeShapeForFullOutput(aS2C0BaseName, S2_C0, aLS2, S2_C0All, di);
683 }
684 }
685 }
686 break;
e98e3990 687 case BOPAlgo_InvalidCurveOnSurface: {
688 if(!aSS1.IsNull()) {
689 S1_COnS++;
690 if(isL1) {
691 Standard_Real aMaxDist = aResult.GetMaxDistance1();
692 Standard_Real aMaxParameter = aResult.GetMaxParameter1();
693 MakeShapeForFullOutput(aS1COnSBaseName, S1_COnS, aLS1, S1_COnSAll, di,
694 Standard_True, aMaxDist, aMaxParameter);
695 }
696 }
697 if(!aSS2.IsNull()) {
698 S2_COnS++;
699 if(isL2) {
700 Standard_Real aMaxDist = aResult.GetMaxDistance2();
701 Standard_Real aMaxParameter = aResult.GetMaxParameter2();
702 MakeShapeForFullOutput(aS2COnSBaseName, S2_COnS, aLS2, S2_COnSAll, di,
703 Standard_True, aMaxDist, aMaxParameter);
704 }
705 }
706 }
707 break;
4e57c75e 708 case BOPAlgo_OperationAborted: {
709 if(!aSS1.IsNull()) S1_OpAb++;
710 if(!aSS2.IsNull()) S2_OpAb++;
711 }
712 break;
713 case BOPAlgo_CheckUnknown:
7fd59977 714 default: {
715 hasUnknown = Standard_True;
716 }
4e57c75e 717 break;
7fd59977 718 } // switch
719 }// faulties
720
e98e3990 721 Standard_Integer FS1 = S1_SelfInt + S1_SmalE + S1_BadF + S1_BadV + S1_BadE + S1_OpAb + S1_C0 + S1_COnS;
7fd59977 722 FS1 += (S1_BadType != 0) ? 1 : 0;
e98e3990 723 Standard_Integer FS2 = S2_SelfInt + S2_SmalE + S2_BadF + S2_BadV + S2_BadE + S2_OpAb + S2_C0 + S2_COnS;
7fd59977 724 FS2 += (S2_BadType != 0) ? 1 : 0;
725
726 // output for first shape
727 di << "Faulties for FIRST shape found : " << FS1 << "\n";
728 if(FS1 != 0) {
729 di << "---------------------------------" << "\n";
730 Standard_CString CString1;
4e57c75e 731 if (S1_BadType != 0)
732 CString1="YES";
733 else
b1d15f53 734 CString1=aChecker.ArgumentTypeMode() ? "NO" : "DISABLED";
7fd59977 735 di << "Shapes are not suppotrted by BOP: " << CString1 << "\n";
736 Standard_CString CString2;
4e57c75e 737 if (S1_SelfInt != 0)
738 CString2="YES";
739 else
b1d15f53 740 CString2=aChecker.SelfInterMode() ? "NO" : "DISABLED";
7fd59977 741 di << "Self-Intersections : " << CString2;
742 if(S1_SelfInt != 0)
743 di << " Cases(" << S1_SelfInt << ") Total shapes(" << S1_SelfIntAll << ")" << "\n";
744 else
745 di << "\n";
4e57c75e 746 Standard_CString CString13;
747 if (S1_OpAb != 0)
748 CString13="YES";
749 else
b1d15f53 750 CString13=aChecker.SelfInterMode() ? "NO" : "DISABLED";
4e57c75e 751 di << "Check for SI has been aborted : " << CString13 << "\n";
7fd59977 752 Standard_CString CString3;
4e57c75e 753 if (S1_SmalE != 0)
754 CString3="YES";
755 else
b1d15f53 756 CString3=aChecker.SmallEdgeMode() ? "NO" : "DISABLED";
7fd59977 757 di << "Too small edges : " << CString3;
758 if(S1_SmalE != 0)
759 di << " Cases(" << S1_SmalE << ") Total shapes(" << S1_SmalEAll << ")" << "\n";
760 else
761 di << "\n";
762 Standard_CString CString4;
4e57c75e 763 if (S1_BadF != 0)
764 CString4="YES";
765 else
b1d15f53 766 CString4=aChecker.RebuildFaceMode() ? "NO" : "DISABLED";
7fd59977 767 di << "Bad faces : " << CString4;
768 if(S1_BadF != 0)
769 di << " Cases(" << S1_BadF << ") Total shapes(" << S1_BadFAll << ")" << "\n";
770 else
771 di << "\n";
772 Standard_CString CString5;
4e57c75e 773 if (S1_BadV != 0)
774 CString5="YES";
775 else
b1d15f53 776 CString5=aChecker.MergeVertexMode() ? "NO" : "DISABLED";
7fd59977 777 di << "Too close vertices : " << CString5;
778 if(S1_BadV != 0)
779 di << " Cases(" << S1_BadV << ") Total shapes(" << S1_BadVAll << ")" << "\n";
780 else
781 di << "\n";
782 Standard_CString CString6;
4e57c75e 783 if (S1_BadE != 0)
784 CString6="YES";
785 else
b1d15f53 786 CString6=aChecker.MergeEdgeMode() ? "NO" : "DISABLED";
7fd59977 787 di << "Too close edges : " << CString6;
788 if(S1_BadE != 0)
789 di << " Cases(" << S1_BadE << ") Total shapes(" << S1_BadEAll << ")" << "\n";
790 else
791 di << "\n";
0e09ee8e 792 Standard_CString CString15;
793 if (S1_C0 != 0)
794 CString15="YES";
795 else
b1d15f53 796 CString15=aChecker.ContinuityMode() ? "NO" : "DISABLED";
0e09ee8e 797 di << "Shapes with Continuity C0 : " << CString15;
798 if(S1_C0 != 0)
799 di << " Cases(" << S1_C0 << ") Total shapes(" << S1_C0All << ")" << "\n";
800 else
801 di << "\n";
e98e3990 802
803 Standard_CString CString17;
804 if (S1_COnS != 0)
805 CString17="YES";
806 else
b1d15f53 807 CString17=aChecker.CurveOnSurfaceMode() ? "NO" : "DISABLED";
e98e3990 808 di << "Invalid Curve on Surface : " << CString17;
809 if(S1_COnS != 0)
810 di << " Cases(" << S1_COnS << ") Total shapes(" << S1_COnSAll << ")" << "\n";
811 else
812 di << "\n";
7fd59977 813 }
814
815 // output for second shape
816 di << "\n";
817 di << "Faulties for SECOND shape found : " << FS2 << "\n";
818 if(FS2 != 0) {
819 di << "---------------------------------" << "\n";
820 Standard_CString CString7;
4e57c75e 821 if (S2_BadType != 0)
822 CString7="YES";
823 else
b1d15f53 824 CString7=aChecker.ArgumentTypeMode() ? "NO" : "DISABLED";
7fd59977 825 di << "Shapes are not suppotrted by BOP: " << CString7 << "\n";
826 Standard_CString CString8;
4e57c75e 827 if (S2_SelfInt != 0)
828 CString8="YES";
829 else
b1d15f53 830 CString8=aChecker.SelfInterMode() ? "NO" : "DISABLED";
7fd59977 831 di << "Self-Intersections : " << CString8;
832 if(S2_SelfInt != 0)
833 di << " Cases(" << S2_SelfInt << ") Total shapes(" << S2_SelfIntAll << ")" << "\n";
834 else
835 di << "\n";
4e57c75e 836
837 Standard_CString CString14;
838 if (S2_OpAb != 0)
839 CString14="YES";
840 else
b1d15f53 841 CString14=aChecker.SelfInterMode() ? "NO" : "DISABLED";
4e57c75e 842 di << "Check for SI has been aborted : " << CString14 << "\n";
7fd59977 843 Standard_CString CString9;
4e57c75e 844 if (S2_SmalE != 0)
845 CString9="YES";
846 else
b1d15f53 847 CString9=aChecker.SmallEdgeMode() ? "NO" : "DISABLED";
7fd59977 848 di << "Too small edges : " << CString9;
849 if(S2_SmalE != 0)
850 di << " Cases(" << S2_SmalE << ") Total shapes(" << S2_SmalEAll << ")" << "\n";
851 else
852 di << "\n";
853 Standard_CString CString10;
4e57c75e 854 if (S2_BadF != 0)
855 CString10="YES";
856 else
b1d15f53 857 CString10=aChecker.RebuildFaceMode() ? "NO" : "DISABLED";
7fd59977 858 di << "Bad faces : " << CString10;
859 if(S2_BadF != 0)
860 di << " Cases(" << S2_BadF << ") Total shapes(" << S2_BadFAll << ")" << "\n";
861 else
862 di << "\n";
863 Standard_CString CString11;
4e57c75e 864 if (S2_BadV != 0)
865 CString11="YES";
866 else
b1d15f53 867 CString11=aChecker.MergeVertexMode() ? "NO" : "DISABLED";
7fd59977 868 di << "Too close vertices : " << CString11;
869 if(S2_BadV != 0)
870 di << " Cases(" << S2_BadV << ") Total shapes(" << S2_BadVAll << ")" << "\n";
871 else
872 di << "\n";
873 Standard_CString CString12;
4e57c75e 874 if (S2_BadE != 0)
875 CString12="YES";
876 else
b1d15f53 877 CString12=aChecker.MergeEdgeMode() ? "NO" : "DISABLED";
7fd59977 878 di << "Too close edges : " << CString12;
879 if(S2_BadE != 0)
880 di << " Cases(" << S2_BadE << ") Total shapes(" << S2_BadEAll << ")" << "\n";
881 else
882 di << "\n";
0e09ee8e 883 Standard_CString CString16;
884 if (S2_C0 != 0)
885 CString16="YES";
886 else
b1d15f53 887 CString16=aChecker.ContinuityMode() ? "NO" : "DISABLED";
0e09ee8e 888 di << "Shapes with Continuity C0 : " << CString16;
889 if(S2_C0 != 0)
890 di << " Cases(" << S2_C0 << ") Total shapes(" << S2_C0All << ")" << "\n";
891 else
892 di << "\n";
7fd59977 893
e98e3990 894 Standard_CString CString18;
895 if (S2_COnS != 0)
896 CString18="YES";
897 else
b1d15f53 898 CString18=aChecker.CurveOnSurfaceMode() ? "NO" : "DISABLED";
e98e3990 899 di << "Invalid Curve on Surface : " << CString18;
900 if(S2_COnS != 0)
901 di << " Cases(" << S2_COnS << ") Total shapes(" << S2_COnSAll << ")" << "\n";
902 else
903 di << "\n";
1b7ae951 904 }
905 // warning
906 if(hasUnknown) {
7fd59977 907 di << "\n";
1b7ae951 908 di << "WARNING: The unexpected test break occurs!" << "\n";
7fd59977 909 }
910 } // full output
911 } // has faulties
912
913 return 0;
914}
e98e3990 915
916//=======================================================================
917//function : xdistef
918//purpose :
919//=======================================================================
920Standard_Integer xdistef(Draw_Interpretor& di,
921 Standard_Integer n,
922 const char** a)
923{
c7b59798 924 if(n < 3) {
43cb0011 925 di << "use xdistef edge face\n";
e98e3990 926 return 1;
927 }
928 //
929 const TopoDS_Shape aS1 = DBRep::Get(a[1]);
930 const TopoDS_Shape aS2 = DBRep::Get(a[2]);
931 //
932 if (aS1.IsNull() || aS2.IsNull()) {
933 di << "null shapes\n";
934 return 1;
935 }
936 //
937 if (aS1.ShapeType() != TopAbs_EDGE ||
938 aS2.ShapeType() != TopAbs_FACE) {
939 di << "type mismatch\n";
940 return 1;
941 }
942 //
943 Standard_Real aMaxDist = 0.0, aMaxPar = 0.0;
944 //
945 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&aS1;
946 const TopoDS_Face& aFace = *(TopoDS_Face*)&aS2;
947 //
948 if(!BOPTools_AlgoTools::ComputeTolerance
949 (aFace, anEdge, aMaxDist, aMaxPar)) {
950 di << "Tolerance cannot be computed\n";
951 return 1;
952 }
953 //
954 di << "Max Distance = " << aMaxDist
955 << "; Parameter on curve = " << aMaxPar << "\n";
956 //
957 return 0;
958}
959
960//=======================================================================
961//function : checkcurveonsurf
962//purpose :
963//=======================================================================
964Standard_Integer checkcurveonsurf(Draw_Interpretor& di,
965 Standard_Integer n,
966 const char** a)
967{
968 if (n != 2) {
969 di << "use checkcurveonsurf shape\n";
970 return 1;
971 }
972 //
973 TopoDS_Shape aS = DBRep::Get(a[1]);
974 if (aS.IsNull()) {
975 di << "null shape\n";
976 return 1;
977 }
978 //
979 Standard_Integer nE, nF, anECounter, aFCounter;
b1d15f53 980 Standard_Real aT, aTolE, aDMax;
e98e3990 981 TopExp_Explorer aExpF, aExpE;
982 char buf[200], aFName[10], anEName[10];
983 NCollection_DataMap<TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> aDMETol;
984 BOPCol_DataMapOfShapeInteger aMSI;
985 //
986 anECounter = 0;
987 aFCounter = 0;
988 //
989 aExpF.Init(aS, TopAbs_FACE);
990 for (; aExpF.More(); aExpF.Next()) {
991 const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
992 //
993 aExpE.Init(aF, TopAbs_EDGE);
994 for (; aExpE.More(); aExpE.Next()) {
995 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
996 //
997 if (!BOPTools_AlgoTools::ComputeTolerance(aF, aE, aDMax, aT)) {
998 continue;
999 }
1000 //
1001 aTolE = BRep_Tool::Tolerance(aE);
1002 if (aDMax < aTolE) {
1003 continue;
1004 }
1005 //
1006 if (aDMETol.IsBound(aE)) {
b1d15f53 1007 Standard_Real& aD = aDMETol.ChangeFind(aE);
e98e3990 1008 if (aDMax > aD) {
b1d15f53 1009 aD = aDMax;
e98e3990 1010 }
1011 }
1012 else {
1013 aDMETol.Bind(aE, aDMax);
1014 }
1015 //
1016 if (anECounter == 0) {
1017 di << "Invalid curves on surface:\n";
1018 }
1019 //
1020 if (aMSI.IsBound(aE)) {
1021 nE = aMSI.Find(aE);
1022 }
1023 else {
1024 nE = anECounter;
1025 aMSI.Bind(aE, nE);
1026 ++anECounter;
1027 }
1028 //
1029 if (aMSI.IsBound(aF)) {
1030 nF = aMSI.Find(aF);
1031 } else {
1032 nF = aFCounter;
1033 aMSI.Bind(aF, nF);
1034 ++aFCounter;
1035 }
1036 //
1037 sprintf(anEName, "e_%d", nE);
1038 sprintf(aFName , "f_%d", nF);
1039 sprintf(buf, "edge %s on face %s (max dist: %3.16f, parameter on curve: %3.16f)\n",
1040 anEName, aFName, aDMax, aT);
1041 di << buf;
1042 //
1043 DBRep::Set(anEName, aE);
1044 DBRep::Set(aFName , aF);
1045 }
1046 }
1047 //
1048 if (anECounter > 0) {
1049 di << "\n\nSugestions to fix the shape:\n";
1050 di << "explode " << a[1] << " e;\n";
1051 //
1052 TopTools_MapOfShape M;
1053 aExpE.Init(aS, TopAbs_EDGE);
1054 for (anECounter = 0; aExpE.More(); aExpE.Next()) {
1055 const TopoDS_Shape& aE = aExpE.Current();
1056 if (!M.Add(aE)) {
1057 continue;
1058 }
1059 ++anECounter;
1060 //
1061 if (!aDMETol.IsBound(aE)) {
1062 continue;
1063 }
1064 //
1065 aTolE = aDMETol.Find(aE);
1066 aTolE *= 1.001;
1067 sprintf(buf, "settolerance %s_%d %3.16f;\n", a[1], anECounter, aTolE);
1068 di << buf;
1069 }
1070 }
1071 else {
1072 di << "This shape seems to be OK.\n";
1073 }
1074 //
1075 return 0;
1076}
1077
63def8e6 1078//=======================================================================
1079//function : MakeShapeForFullOutput
1080//purpose :
1081//=======================================================================
1082void MakeShapeForFullOutput (const TCollection_AsciiString & aBaseName,
1083 const Standard_Integer aIndex,
e98e3990 1084 const BOPCol_ListOfShape & aList,
63def8e6 1085 Standard_Integer& aCount,
e98e3990 1086 Draw_Interpretor& di,
1087 Standard_Boolean bCurveOnSurf,
1088 Standard_Real aMaxDist,
1089 Standard_Real aMaxParameter)
63def8e6 1090{
1091 TCollection_AsciiString aNum(aIndex);
1092 TCollection_AsciiString aName = aBaseName + aNum;
1093 Standard_CString name = aName.ToCString();
1094
1095 TopoDS_Compound cmp;
1096 BRep_Builder BB;
1097 BB.MakeCompound(cmp);
1098
1099 BOPCol_ListIteratorOfListOfShape anIt(aList);
1100 for(; anIt.More(); anIt.Next()) {
1101 const TopoDS_Shape & aS = anIt.Value();
1102 BB.Add(cmp, aS);
1103 aCount++;
1104 }
e98e3990 1105 di << "Made faulty shape: " << name;
1106 //
1107 if (bCurveOnSurf) {
1108 di << " (MaxDist = " << aMaxDist
1109 << ", MaxPar = " << aMaxParameter << ")";
1110 }
1111 //
1112 di << "\n";
1113 //
63def8e6 1114 DBRep::Set(name, cmp);
1115}