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 | |
23 | #include <TopoDS_Shape.hxx> |
24 | #include <TopoDS_Compound.hxx> |
25 | #include <BRep_Builder.hxx> |
63def8e6 |
26 | #include <BRepBuilderAPI_Copy.hxx> |
7fd59977 |
27 | |
7fd59977 |
28 | #include <DBRep.hxx> |
4e57c75e |
29 | #include <Draw.hxx> |
80db5701 |
30 | |
31 | #include <BOPCol_ListOfShape.hxx> |
32 | |
33 | #include <BOPDS_DS.hxx> |
63def8e6 |
34 | #include <BOPDS_MapOfPassKey.hxx> |
80db5701 |
35 | |
4e57c75e |
36 | #include <BOPAlgo_CheckerSI.hxx> |
4e57c75e |
37 | #include <BOPAlgo_ArgumentAnalyzer.hxx> |
38 | #include <BOPAlgo_CheckResult.hxx> |
7fd59977 |
39 | |
63def8e6 |
40 | #include <BOPTest_Chronometer.hxx> |
41 | // |
7fd59977 |
42 | static |
63def8e6 |
43 | void MakeShapeForFullOutput (const TCollection_AsciiString&, |
44 | const Standard_Integer, |
45 | const BOPCol_ListOfShape&, |
46 | Standard_Integer& , |
47 | Draw_Interpretor&); |
7fd59977 |
48 | // |
63def8e6 |
49 | static Standard_Integer bopcheck (Draw_Interpretor&, Standard_Integer, const char** ); |
50 | static Standard_Integer bopargcheck(Draw_Interpretor&, Standard_Integer, const char** ); |
7fd59977 |
51 | |
52 | //======================================================================= |
53 | //function : CheckCommands |
54 | //purpose : |
55 | //======================================================================= |
63def8e6 |
56 | void BOPTest::CheckCommands(Draw_Interpretor& theCommands) |
7fd59977 |
57 | { |
58 | static Standard_Boolean done = Standard_False; |
59 | if (done) |
60 | return; |
61 | |
62 | done = Standard_True; |
63 | // Chapter's name |
64 | const char* g = "CCR commands"; |
65 | // |
6f31882a |
66 | theCommands.Add("bopcheck", |
67 | "Use >bopcheck Shape [level of check: 0(V/V) - 5(all)]", |
68 | __FILE__, bopcheck, g); |
69 | theCommands.Add("bopargcheck" , |
70 | "Use bopargcheck without parameters to get ", |
71 | __FILE__, bopargcheck, g); |
7fd59977 |
72 | } |
63def8e6 |
73 | //======================================================================= |
74 | //class : BOPTest_Interf |
75 | //purpose : Auxiliary class |
76 | //======================================================================= |
77 | class BOPTest_Interf { |
78 | public: |
79 | BOPTest_Interf() : myIndex1(-1), myIndex2(-1), myType(-1) { |
80 | } |
81 | // |
82 | ~BOPTest_Interf() { |
83 | } |
84 | // |
85 | void SetIndices(const Standard_Integer theIndex1, |
86 | const Standard_Integer theIndex2) { |
87 | myIndex1=theIndex1; |
88 | myIndex2=theIndex2; |
89 | } |
90 | // |
91 | void Indices(Standard_Integer& theIndex1, |
92 | Standard_Integer& theIndex2) const { |
93 | theIndex1=myIndex1; |
94 | theIndex2=myIndex2; |
95 | } |
96 | // |
97 | void SetType(const Standard_Integer theType) { |
98 | myType=theType; |
99 | } |
100 | // |
101 | Standard_Integer Type() const { |
102 | return myType; |
103 | } |
104 | // |
105 | bool operator < (const BOPTest_Interf& aOther) const { |
106 | bool bFlag; |
107 | // |
108 | if (myType==aOther.myType) { |
109 | if (myIndex1 == aOther.myIndex1) { |
110 | bFlag=(myIndex2 < aOther.myIndex2); |
111 | } |
112 | else { |
113 | bFlag=(myIndex1 < aOther.myIndex1); |
114 | } |
115 | } |
116 | else { |
117 | bFlag=(myType < aOther.myType); |
118 | } |
119 | // |
120 | return bFlag; |
121 | } |
122 | // |
123 | protected: |
124 | Standard_Integer myIndex1; |
125 | Standard_Integer myIndex2; |
126 | Standard_Integer myType; |
127 | }; |
7fd59977 |
128 | //======================================================================= |
129 | //function : bopcheck |
130 | //purpose : |
131 | //======================================================================= |
63def8e6 |
132 | Standard_Integer bopcheck (Draw_Interpretor& di, |
133 | Standard_Integer n, |
134 | const char** a ) |
7fd59977 |
135 | { |
7fd59977 |
136 | if (n<2) { |
63def8e6 |
137 | di << " Use > bopcheck Shape [level of check: 0 - 9] [-t -s]" << "\n"; |
6f31882a |
138 | di << " The level of check defines "; |
80db5701 |
139 | di << " which interferences will be checked:\n"; |
140 | di << " 0 - V/V only\n"; |
141 | di << " 1 - V/V, V/E\n"; |
142 | di << " 2 - V/V, V/E, E/E\n"; |
143 | di << " 3 - V/V, V/E, E/E , V/F\n"; |
144 | di << " 4 - V/V, V/E, E/E, V/F , E/F\n"; |
145 | di << " 5 - V/V, V/E, E/E, V/F, E/F, F/F;\n"; |
146 | di << " 6 - V/V, V/E, E/E, V/F, E/F, F/F, V/Z\n"; |
147 | di << " 7 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z\n"; |
148 | di << " 8 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z, F/Z\n"; |
149 | di << " 9 - V/V, V/E, E/E, V/F, E/F, F/F, E/Z, F/Z, Z/Z\n"; |
150 | di << " Default level is 9\n"; |
7fd59977 |
151 | return 1; |
152 | } |
80db5701 |
153 | // |
154 | TopoDS_Shape aS = DBRep::Get(a[1]); |
155 | if (aS.IsNull()) { |
4e57c75e |
156 | di << "null shapes are not allowed here!"; |
157 | return 1; |
158 | } |
7fd59977 |
159 | // |
63def8e6 |
160 | Standard_Boolean bRunParallel, bShowTime; |
161 | Standard_Integer i, aLevel, aNbInterfTypes; |
80db5701 |
162 | // |
163 | aNbInterfTypes=BOPDS_DS::NbInterfTypes(); |
164 | // |
63def8e6 |
165 | aLevel=aNbInterfTypes-1; |
166 | // |
167 | if (n>2) { |
168 | aLevel=Draw::Atoi(a[2]); |
169 | } |
170 | // |
171 | if (aLevel < 0 || aLevel > aNbInterfTypes-1) { |
80db5701 |
172 | di << "Invalid level"; |
173 | return 1; |
174 | } |
63def8e6 |
175 | // |
176 | bShowTime=Standard_False; |
177 | bRunParallel=Standard_True; |
178 | for (i=3; i<n; ++i) { |
179 | if (!strcmp(a[i], "-s")) { |
180 | bRunParallel=Standard_False; |
181 | } |
182 | else if (!strcmp(a[i], "-t")) { |
183 | bShowTime=Standard_True; |
184 | } |
185 | } |
186 | // |
187 | //aLevel = (n==3) ? Draw::Atoi(a[2]) : aNbInterfTypes-1; |
80db5701 |
188 | //------------------------------------------------------------------- |
63def8e6 |
189 | char buf[256], aName1[32], aName2[32]; |
190 | char aInterfTypes[10][4] = { |
80db5701 |
191 | "V/V", "V/E", "E/E","V/F", "E/F", "F/F", "V/Z", "E/Z", "F/Z", "Z/Z" |
192 | }; |
80db5701 |
193 | // |
63def8e6 |
194 | Standard_Integer iErr, iCnt, n1, n2, iT; |
195 | TopAbs_ShapeEnum aType1, aType2; |
196 | BOPAlgo_CheckerSI aChecker; |
197 | BOPCol_ListOfShape aLS; |
198 | BOPDS_MapIteratorMapOfPassKey aItMPK; |
199 | BOPTime_Chronometer aChrono; |
200 | // |
201 | if (aLevel < (aNbInterfTypes-1)) { |
6f31882a |
202 | di << "Info:\nThe level of check is set to " |
63def8e6 |
203 | << aInterfTypes[aLevel] << ", i.e. intersection(s)\n"; |
204 | |
205 | for (i=aLevel+1; i<aNbInterfTypes; ++i) { |
206 | di << aInterfTypes[i]; |
80db5701 |
207 | if (i<aNbInterfTypes-1) { |
c1fe53c6 |
208 | di << ", "; |
209 | } |
210 | } |
211 | di << " will not be checked.\n\n"; |
212 | } |
80db5701 |
213 | // |
63def8e6 |
214 | aLS.Append(aS); |
215 | aChecker.SetArguments(aLS); |
216 | aChecker.SetLevelOfCheck(aLevel); |
217 | aChecker.SetRunParallel(bRunParallel); |
80db5701 |
218 | // |
63def8e6 |
219 | aChrono.Start(); |
4e57c75e |
220 | // |
221 | aChecker.Perform(); |
4e57c75e |
222 | // |
63def8e6 |
223 | aChrono.Stop(); |
4e57c75e |
224 | // |
63def8e6 |
225 | iErr=aChecker.ErrorStatus(); |
4e57c75e |
226 | // |
63def8e6 |
227 | const BOPDS_DS& aDS=*(aChecker.PDS()); |
228 | // |
229 | const BOPDS_MapOfPassKey& aMPK=aDS.Interferences(); |
230 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
231 | using namespace std; |
232 | vector <BOPTest_Interf> aVec; |
233 | vector <BOPTest_Interf>::iterator aIt; |
234 | BOPTest_Interf aBInterf; |
235 | // |
236 | aItMPK.Initialize(aMPK); |
237 | for (; aItMPK.More(); aItMPK.Next()) { |
238 | const BOPDS_PassKey& aPK=aItMPK.Value(); |
239 | aPK.Ids(n1, n2); |
240 | if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) { |
241 | continue; |
242 | } |
243 | // |
244 | const BOPDS_ShapeInfo& aSI1=aDS.ShapeInfo(n1); |
245 | const BOPDS_ShapeInfo& aSI2=aDS.ShapeInfo(n2); |
246 | aType1=aSI1.ShapeType(); |
247 | aType2=aSI2.ShapeType(); |
248 | // |
249 | iT=BOPDS_Tools::TypeToInteger(aType1, aType2); |
250 | // |
251 | aBInterf.SetIndices(n1, n2); |
252 | aBInterf.SetType(iT); |
253 | // |
254 | aVec.push_back(aBInterf); |
255 | } |
256 | // |
257 | sort( aVec.begin(), aVec.end(), less<BOPTest_Interf>()); |
258 | // |
259 | iCnt=0; |
260 | for (aIt=aVec.begin(); aIt!=aVec.end(); aIt++) { |
261 | const BOPTest_Interf& aBI=*aIt; |
262 | // |
263 | aBI.Indices(n1, n2); |
264 | if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) { |
265 | continue; |
7fd59977 |
266 | } |
63def8e6 |
267 | // |
268 | const TopoDS_Shape& aS1=aDS.Shape(n1); |
269 | const TopoDS_Shape& aS2=aDS.Shape(n2); |
270 | // |
271 | iT=aBI.Type(); |
272 | di << aInterfTypes[iT] << ": "; |
273 | // |
274 | sprintf(aName1, "x%d", n1); |
275 | //sprintf(aName1, "x%d", iCnt); |
276 | DBRep::Set (aName1, aS1); |
277 | // |
278 | ++iCnt; |
279 | sprintf(aName2, "x%d", n2); |
280 | //sprintf(aName2, "x%d", iCnt); |
281 | DBRep::Set (aName2, aS2); |
282 | ++iCnt; |
283 | // |
284 | sprintf(buf, "%s %s \n", aName1, aName2); |
285 | di << buf; |
7fd59977 |
286 | } |
6f31882a |
287 | // |
4e57c75e |
288 | if (iErr) { |
6f31882a |
289 | di << "There were errors during the operation, "; |
290 | di << "so the list may be incomplete." << "\n"; |
4e57c75e |
291 | } |
6f31882a |
292 | // |
63def8e6 |
293 | if (!iCnt) { |
7fd59977 |
294 | di << " This shape seems to be OK." << "\n"; |
295 | } |
63def8e6 |
296 | if (bShowTime) { |
297 | Standard_Real aTime; |
298 | // |
299 | aTime=aChrono.Time(); |
300 | Sprintf(buf, " Tps: %7.2lf\n", aTime); |
301 | di << buf; |
7fd59977 |
302 | } |
63def8e6 |
303 | return 0; |
7fd59977 |
304 | } |
6f31882a |
305 | //======================================================================= |
306 | //function : bopargcheck |
307 | //purpose : |
308 | //======================================================================= |
63def8e6 |
309 | Standard_Integer bopargcheck (Draw_Interpretor& di, |
310 | Standard_Integer n, |
311 | const char** a ) |
7fd59977 |
312 | { |
313 | if (n<2) { |
314 | di << "\n"; |
6f31882a |
315 | di << " Use >bopargcheck Shape1 [[Shape2] "; |
316 | di << "[-F/O/C/T/S/U] [/R|F|T|V|E|I|P]] [#BF]" << "\n" << "\n"; |
7fd59977 |
317 | di << " -<Boolean Operation>" << "\n"; |
318 | di << " F (fuse)" << "\n"; |
319 | di << " O (common)" << "\n"; |
320 | di << " C (cut)" << "\n"; |
321 | di << " T (cut21)" << "\n"; |
322 | di << " S (section)" << "\n"; |
323 | di << " U (unknown)" << "\n"; |
6f31882a |
324 | di << " For example: \"bopargcheck s1 s2 -F\" enables" ; |
63def8e6 |
325 | di << " checking for Fuse operation" << "\n"; |
7fd59977 |
326 | di << " default - section" << "\n" << "\n"; |
7fd59977 |
327 | di << " /<Test Options>" << "\n"; |
7fd59977 |
328 | di << " R (disable small edges (shrank range) test)" << "\n"; |
7fd59977 |
329 | di << " F (disable faces verification test)" << "\n"; |
7fd59977 |
330 | di << " T (disable tangent faces searching test)" << "\n"; |
7fd59977 |
331 | di << " V (disable test possibility to merge vertices)" << "\n"; |
7fd59977 |
332 | di << " E (disable test possibility to merge edges)" << "\n"; |
333 | di << " I (disable self-interference test)" << "\n"; |
334 | di << " P (disable shape type test)" << "\n"; |
0e09ee8e |
335 | di << " C (disable test for shape continuity)" << "\n"; |
6f31882a |
336 | di << " For example: \"bopargcheck s1 s2 /RI\" disables "; |
337 | di << "small edge detection and self-intersection detection" << "\n"; |
7fd59977 |
338 | di << " default - all options are enabled" << "\n" << "\n"; |
339 | di << " #<Additional Test Options>" << "\n"; |
340 | di << " B (stop test on first faulty found); default OFF" << "\n"; |
6f31882a |
341 | di << " F (full output for faulty shapes); default - output "; |
342 | di << "in a short format" << "\n" << "\n"; |
343 | di << " NOTE: <Boolean Operation> and <Test Options> are "; |
344 | di << "used only for couple" << "\n"; |
345 | di << " of argument shapes, except I and P options "; |
346 | di << "that are always used for" << "\n"; |
347 | di << " couple of shapes as well as for "; |
348 | di <<"single shape test." << "\n"; |
7fd59977 |
349 | return 1; |
350 | } |
351 | |
6f31882a |
352 | TopoDS_Shape aS1 = DBRep::Get(a[1]); |
7fd59977 |
353 | |
6f31882a |
354 | if(aS1.IsNull()) { |
7fd59977 |
355 | di << "Error: null shape not allowed!" << "\n"; |
6f31882a |
356 | di << "Type bopargcheck without arguments for more "; |
357 | di <<"information" << "\n"; |
7fd59977 |
358 | return 1; |
359 | } |
360 | |
361 | Standard_Boolean isBO = Standard_False; |
362 | Standard_Integer indxBO = 0; |
363 | Standard_Boolean isOP = Standard_False; |
364 | Standard_Integer indxOP = 0; |
365 | Standard_Boolean isAD = Standard_False; |
366 | Standard_Integer indxAD = 0; |
367 | Standard_Boolean isS2 = Standard_False; |
368 | Standard_Integer indxS2 = 0; |
369 | |
370 | if(n >= 3) { |
371 | Standard_Integer iIndex = 0; |
372 | for(iIndex = 2; iIndex < n; iIndex++) { |
373 | if(a[iIndex][0] == '-') |
374 | { |
375 | isBO = Standard_True; |
376 | indxBO = iIndex; |
377 | } |
378 | //else if(a[iIndex][0] == '+') |
379 | else if(a[iIndex][0] == '/') |
380 | { |
381 | isOP = Standard_True; |
382 | indxOP = iIndex; |
383 | } |
384 | else if(a[iIndex][0] == '#') |
385 | { |
386 | isAD = Standard_True; |
387 | indxAD = iIndex; |
388 | } |
389 | else { |
390 | isS2 = Standard_True; |
391 | indxS2 = iIndex; |
392 | } |
393 | } |
394 | } |
395 | |
396 | // set & test second shape |
4e57c75e |
397 | TopoDS_Shape aS22, aS2; |
7fd59977 |
398 | if(isS2) { |
399 | if(indxS2 != 2) { |
400 | di << "Error: second shape should follow the first one!" << "\n"; |
401 | di << "Type bopargcheck without arguments for more information" << "\n"; |
402 | return 1; |
403 | } |
404 | else { |
4e57c75e |
405 | aS22 = DBRep::Get(a[2]); |
406 | if(aS22.IsNull()) { |
7fd59977 |
407 | di << "Error: second shape is null!" << "\n"; |
408 | di << "Type bopargcheck without arguments for more information" << "\n"; |
409 | return 1; |
410 | } |
411 | } |
412 | } |
413 | |
414 | // init checker |
4e57c75e |
415 | BOPAlgo_ArgumentAnalyzer aChecker; |
7fd59977 |
416 | aChecker.SetShape1(aS1); |
417 | |
418 | // set default options (always tested!) for single and couple shapes |
419 | aChecker.ArgumentTypeMode() = Standard_True; |
420 | aChecker.SelfInterMode() = Standard_True; |
0e09ee8e |
421 | aChecker.SmallEdgeMode() = Standard_True; |
422 | aChecker.RebuildFaceMode() = Standard_True; |
423 | aChecker.ContinuityMode() = Standard_True; |
7fd59977 |
424 | |
425 | // test & set options and operation for two shapes |
4e57c75e |
426 | if(!aS22.IsNull()) { |
427 | aS2 = BRepBuilderAPI_Copy(aS22).Shape(); |
7fd59977 |
428 | aChecker.SetShape2(aS2); |
429 | // set operation (default - Section) |
430 | if(isBO) { |
431 | if(a[indxBO][1] == 'F' || a[indxBO][1] == 'f') { |
4e57c75e |
432 | aChecker.OperationType() = BOPAlgo_FUSE; |
7fd59977 |
433 | } |
434 | else if(a[indxBO][1] == 'O' || a[indxBO][1] == 'o') { |
4e57c75e |
435 | aChecker.OperationType() = BOPAlgo_COMMON; |
7fd59977 |
436 | } |
437 | else if(a[indxBO][1] == 'C' || a[indxBO][1] == 'c') { |
4e57c75e |
438 | aChecker.OperationType() = BOPAlgo_CUT; |
7fd59977 |
439 | } |
440 | else if(a[indxBO][1] == 'T' || a[indxBO][1] == 't') { |
4e57c75e |
441 | aChecker.OperationType() = BOPAlgo_CUT21; |
7fd59977 |
442 | } |
443 | else if(a[indxBO][1] == 'S' || a[indxBO][1] == 's') { |
4e57c75e |
444 | aChecker.OperationType() = BOPAlgo_SECTION; |
7fd59977 |
445 | } |
446 | else if(a[indxBO][1] == 'U' || a[indxBO][1] == 'u') { |
4e57c75e |
447 | aChecker.OperationType() = BOPAlgo_UNKNOWN; |
7fd59977 |
448 | } |
449 | else { |
450 | di << "Error: invalid boolean operation type!" << "\n"; |
451 | di << "Type bopargcheck without arguments for more information" << "\n"; |
452 | return 1; |
453 | } |
454 | } |
455 | else |
4e57c75e |
456 | aChecker.OperationType() = BOPAlgo_SECTION; |
7fd59977 |
457 | |
7fd59977 |
458 | aChecker.TangentMode() = Standard_True; |
459 | aChecker.MergeVertexMode() = Standard_True; |
460 | aChecker.MergeEdgeMode() = Standard_True; |
7fd59977 |
461 | } |
0e09ee8e |
462 | |
463 | // set options (default - all ON) |
464 | if(isOP) { |
465 | Standard_Integer ind = 1; |
466 | while(a[indxOP][ind] != 0) { |
467 | if(a[indxOP][ind] == 'R' || a[indxOP][ind] == 'r') { |
468 | aChecker.SmallEdgeMode() = Standard_False; |
469 | } |
470 | else if(a[indxOP][ind] == 'F' || a[indxOP][ind] == 'f') { |
471 | aChecker.RebuildFaceMode() = Standard_False; |
472 | } |
473 | else if(a[indxOP][ind] == 'T' || a[indxOP][ind] == 't') { |
474 | aChecker.TangentMode() = Standard_False; |
7fd59977 |
475 | } |
0e09ee8e |
476 | else if(a[indxOP][ind] == 'V' || a[indxOP][ind] == 'v') { |
477 | aChecker.MergeVertexMode() = Standard_False; |
478 | } |
479 | else if(a[indxOP][ind] == 'E' || a[indxOP][ind] == 'e') { |
480 | aChecker.MergeEdgeMode() = Standard_False; |
481 | } |
482 | else if(a[indxOP][ind] == 'I' || a[indxOP][ind] == 'i') { |
483 | aChecker.SelfInterMode() = Standard_False; |
484 | } |
485 | else if(a[indxOP][ind] == 'P' || a[indxOP][ind] == 'p') { |
486 | aChecker.ArgumentTypeMode() = Standard_False; |
487 | } |
488 | else if(a[indxOP][ind] == 'C' || a[indxOP][ind] == 'c') { |
489 | aChecker.ContinuityMode() = Standard_False; |
490 | } |
491 | else { |
492 | di << "Error: invalid test option(s)!" << "\n"; |
493 | di << "Type bopargcheck without arguments for more information" << "\n"; |
494 | return 1; |
495 | } |
496 | ind++; |
7fd59977 |
497 | } |
498 | } |
499 | |
500 | // set additional options |
501 | Standard_Boolean fullOutput = Standard_False; |
502 | if(isAD) { |
503 | Standard_Integer ind = 1; |
504 | while(a[indxAD][ind] != 0) { |
505 | if(a[indxAD][ind] == 'B' || a[indxAD][ind] == 'b') { |
506 | aChecker.StopOnFirstFaulty() = Standard_True; |
507 | } |
508 | else if(a[indxAD][ind] == 'F' || a[indxAD][ind] == 'f') { |
509 | fullOutput = Standard_True; |
510 | } |
511 | else { |
512 | di << "Error: invalid additional test option(s)!" << "\n"; |
513 | di << "Type bopargcheck without arguments for more information" << "\n"; |
514 | return 1; |
515 | } |
516 | ind++; |
517 | } |
518 | } |
519 | |
520 | // run checker |
521 | aChecker.Perform(); |
522 | |
523 | // process result of checking |
524 | if(!aChecker.HasFaulty()) { |
525 | di << "Shape(s) seem(s) to be valid for BOP." << "\n"; |
526 | } |
527 | else { |
528 | if(!fullOutput) { |
529 | di << "Faulties, that can not be treated by BOP, are detected." << "\n"; |
530 | } |
531 | else { |
4e57c75e |
532 | const BOPAlgo_ListOfCheckResult& aResultList = aChecker.GetCheckResult(); |
533 | BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResultList); |
7fd59977 |
534 | |
535 | Standard_Integer S1_BadType = 0, S1_SelfInt = 0, S1_SmalE = 0, S1_BadF = 0, S1_BadV = 0, S1_BadE = 0; |
536 | Standard_Integer S1_SelfIntAll = 0, S1_SmalEAll = 0, S1_BadFAll = 0, S1_BadVAll = 0, S1_BadEAll = 0; |
537 | Standard_Integer S2_BadType = 0, S2_SelfInt = 0, S2_SmalE = 0, S2_BadF = 0, S2_BadV = 0, S2_BadE = 0; |
538 | Standard_Integer S2_SelfIntAll = 0, S2_SmalEAll = 0, S2_BadFAll = 0, S2_BadVAll = 0, S2_BadEAll = 0; |
4e57c75e |
539 | Standard_Integer S1_OpAb = 0, S2_OpAb = 0; |
0e09ee8e |
540 | Standard_Integer S1_C0 = 0, S2_C0 = 0, S1_C0All = 0, S2_C0All = 0; |
7fd59977 |
541 | Standard_Boolean hasUnknown = Standard_False; |
542 | |
543 | TCollection_AsciiString aS1SIBaseName("s1si_"); |
544 | TCollection_AsciiString aS1SEBaseName("s1se_"); |
545 | TCollection_AsciiString aS1BFBaseName("s1bf_"); |
546 | TCollection_AsciiString aS1BVBaseName("s1bv_"); |
547 | TCollection_AsciiString aS1BEBaseName("s1be_"); |
0e09ee8e |
548 | TCollection_AsciiString aS1C0BaseName("s1C0_"); |
7fd59977 |
549 | TCollection_AsciiString aS2SIBaseName("s2si_"); |
550 | TCollection_AsciiString aS2SEBaseName("s2se_"); |
551 | TCollection_AsciiString aS2BFBaseName("s2bf_"); |
552 | TCollection_AsciiString aS2BVBaseName("s2bv_"); |
553 | TCollection_AsciiString aS2BEBaseName("s2be_"); |
0e09ee8e |
554 | TCollection_AsciiString aS2C0BaseName("s2C0_"); |
7fd59977 |
555 | |
556 | for(; anIt.More(); anIt.Next()) { |
4e57c75e |
557 | const BOPAlgo_CheckResult& aResult = anIt.Value(); |
7fd59977 |
558 | const TopoDS_Shape & aSS1 = aResult.GetShape1(); |
559 | const TopoDS_Shape & aSS2 = aResult.GetShape2(); |
4e57c75e |
560 | const BOPCol_ListOfShape & aLS1 = aResult.GetFaultyShapes1(); |
561 | const BOPCol_ListOfShape & aLS2 = aResult.GetFaultyShapes2(); |
7fd59977 |
562 | Standard_Boolean isL1 = !aLS1.IsEmpty(); |
563 | Standard_Boolean isL2 = !aLS2.IsEmpty(); |
564 | |
565 | switch(aResult.GetCheckStatus()) { |
4e57c75e |
566 | case BOPAlgo_BadType: { |
7fd59977 |
567 | if(!aSS1.IsNull()) S1_BadType++; |
568 | if(!aSS2.IsNull()) S2_BadType++; |
569 | } |
4e57c75e |
570 | break; |
571 | case BOPAlgo_SelfIntersect: { |
7fd59977 |
572 | if(!aSS1.IsNull()) { |
573 | S1_SelfInt++; |
574 | if(isL1) |
575 | MakeShapeForFullOutput(aS1SIBaseName, S1_SelfInt, aLS1, S1_SelfIntAll, di); |
576 | } |
577 | if(!aSS2.IsNull()) { |
578 | S2_SelfInt++; |
579 | if(isL2) |
580 | MakeShapeForFullOutput(aS2SIBaseName, S2_SelfInt, aLS2, S2_SelfIntAll, di); |
581 | } |
582 | } |
4e57c75e |
583 | break; |
584 | case BOPAlgo_TooSmallEdge: { |
7fd59977 |
585 | if(!aSS1.IsNull()) { |
586 | S1_SmalE++; |
587 | if(isL1) |
588 | MakeShapeForFullOutput(aS1SEBaseName, S1_SmalE, aLS1, S1_SmalEAll, di); |
589 | } |
590 | if(!aSS2.IsNull()) { |
591 | S2_SmalE++; |
592 | if(isL2) |
593 | MakeShapeForFullOutput(aS2SEBaseName, S2_SmalE, aLS2, S2_SmalEAll, di); |
594 | } |
595 | } |
4e57c75e |
596 | break; |
597 | case BOPAlgo_NonRecoverableFace: { |
7fd59977 |
598 | if(!aSS1.IsNull()) { |
599 | S1_BadF++; |
600 | if(isL1) |
601 | MakeShapeForFullOutput(aS1BFBaseName, S1_BadF, aLS1, S1_BadFAll, di); |
602 | } |
603 | if(!aSS2.IsNull()) { |
604 | S2_BadF++; |
605 | if(isL2) |
606 | MakeShapeForFullOutput(aS2BFBaseName, S2_BadF, aLS2, S2_BadFAll, di); |
607 | } |
608 | } |
4e57c75e |
609 | break; |
610 | case BOPAlgo_IncompatibilityOfVertex: { |
7fd59977 |
611 | if(!aSS1.IsNull()) { |
612 | S1_BadV++; |
613 | if(isL1) { |
614 | MakeShapeForFullOutput(aS1BVBaseName, S1_BadV, aLS1, S1_BadVAll, di); |
4e57c75e |
615 | } |
7fd59977 |
616 | } |
617 | if(!aSS2.IsNull()) { |
618 | S2_BadV++; |
619 | if(isL2){ |
620 | MakeShapeForFullOutput(aS2BVBaseName, S2_BadV, aLS2, S2_BadVAll, di); |
4e57c75e |
621 | } |
7fd59977 |
622 | } |
623 | } |
4e57c75e |
624 | break; |
625 | case BOPAlgo_IncompatibilityOfEdge: { |
7fd59977 |
626 | if(!aSS1.IsNull()) { |
627 | S1_BadE++; |
628 | if(isL1) { |
629 | MakeShapeForFullOutput(aS1BEBaseName, S1_BadE, aLS1, S1_BadEAll, di); |
4e57c75e |
630 | } |
7fd59977 |
631 | } |
632 | if(!aSS2.IsNull()) { |
633 | S2_BadE++; |
634 | if(isL2) { |
635 | MakeShapeForFullOutput(aS2BEBaseName, S2_BadE, aLS2, S2_BadEAll, di); |
4e57c75e |
636 | } |
7fd59977 |
637 | } |
638 | } |
4e57c75e |
639 | break; |
640 | case BOPAlgo_IncompatibilityOfFace: { |
7fd59977 |
641 | // not yet implemented |
642 | } |
4e57c75e |
643 | break; |
0e09ee8e |
644 | case BOPAlgo_GeomAbs_C0: { |
645 | if(!aSS1.IsNull()) { |
646 | S1_C0++; |
647 | if(isL1) { |
648 | MakeShapeForFullOutput(aS1C0BaseName, S1_C0, aLS1, S1_C0All, di); |
649 | } |
650 | } |
651 | if(!aSS2.IsNull()) { |
652 | S2_C0++; |
653 | if(isL2) { |
654 | MakeShapeForFullOutput(aS2C0BaseName, S2_C0, aLS2, S2_C0All, di); |
655 | } |
656 | } |
657 | } |
658 | break; |
4e57c75e |
659 | case BOPAlgo_OperationAborted: { |
660 | if(!aSS1.IsNull()) S1_OpAb++; |
661 | if(!aSS2.IsNull()) S2_OpAb++; |
662 | } |
663 | break; |
664 | case BOPAlgo_CheckUnknown: |
7fd59977 |
665 | default: { |
666 | hasUnknown = Standard_True; |
667 | } |
4e57c75e |
668 | break; |
7fd59977 |
669 | } // switch |
670 | }// faulties |
671 | |
0e09ee8e |
672 | Standard_Integer FS1 = S1_SelfInt + S1_SmalE + S1_BadF + S1_BadV + S1_BadE + S1_OpAb + S1_C0; |
7fd59977 |
673 | FS1 += (S1_BadType != 0) ? 1 : 0; |
0e09ee8e |
674 | Standard_Integer FS2 = S2_SelfInt + S2_SmalE + S2_BadF + S2_BadV + S2_BadE + S2_OpAb + S2_C0; |
7fd59977 |
675 | FS2 += (S2_BadType != 0) ? 1 : 0; |
676 | |
677 | // output for first shape |
678 | di << "Faulties for FIRST shape found : " << FS1 << "\n"; |
679 | if(FS1 != 0) { |
680 | di << "---------------------------------" << "\n"; |
681 | Standard_CString CString1; |
4e57c75e |
682 | if (S1_BadType != 0) |
683 | CString1="YES"; |
684 | else |
685 | CString1="NO"; |
7fd59977 |
686 | di << "Shapes are not suppotrted by BOP: " << CString1 << "\n"; |
687 | Standard_CString CString2; |
4e57c75e |
688 | if (S1_SelfInt != 0) |
689 | CString2="YES"; |
690 | else |
691 | CString2="NO"; |
7fd59977 |
692 | di << "Self-Intersections : " << CString2; |
693 | if(S1_SelfInt != 0) |
694 | di << " Cases(" << S1_SelfInt << ") Total shapes(" << S1_SelfIntAll << ")" << "\n"; |
695 | else |
696 | di << "\n"; |
4e57c75e |
697 | Standard_CString CString13; |
698 | if (S1_OpAb != 0) |
699 | CString13="YES"; |
700 | else |
701 | CString13="NO"; |
702 | di << "Check for SI has been aborted : " << CString13 << "\n"; |
7fd59977 |
703 | Standard_CString CString3; |
4e57c75e |
704 | if (S1_SmalE != 0) |
705 | CString3="YES"; |
706 | else |
707 | CString3="NO"; |
7fd59977 |
708 | di << "Too small edges : " << CString3; |
709 | if(S1_SmalE != 0) |
710 | di << " Cases(" << S1_SmalE << ") Total shapes(" << S1_SmalEAll << ")" << "\n"; |
711 | else |
712 | di << "\n"; |
713 | Standard_CString CString4; |
4e57c75e |
714 | if (S1_BadF != 0) |
715 | CString4="YES"; |
716 | else |
717 | CString4="NO"; |
7fd59977 |
718 | di << "Bad faces : " << CString4; |
719 | if(S1_BadF != 0) |
720 | di << " Cases(" << S1_BadF << ") Total shapes(" << S1_BadFAll << ")" << "\n"; |
721 | else |
722 | di << "\n"; |
723 | Standard_CString CString5; |
4e57c75e |
724 | if (S1_BadV != 0) |
725 | CString5="YES"; |
726 | else |
727 | CString5="NO"; |
7fd59977 |
728 | di << "Too close vertices : " << CString5; |
729 | if(S1_BadV != 0) |
730 | di << " Cases(" << S1_BadV << ") Total shapes(" << S1_BadVAll << ")" << "\n"; |
731 | else |
732 | di << "\n"; |
733 | Standard_CString CString6; |
4e57c75e |
734 | if (S1_BadE != 0) |
735 | CString6="YES"; |
736 | else |
737 | CString6="NO"; |
7fd59977 |
738 | di << "Too close edges : " << CString6; |
739 | if(S1_BadE != 0) |
740 | di << " Cases(" << S1_BadE << ") Total shapes(" << S1_BadEAll << ")" << "\n"; |
741 | else |
742 | di << "\n"; |
0e09ee8e |
743 | Standard_CString CString15; |
744 | if (S1_C0 != 0) |
745 | CString15="YES"; |
746 | else |
747 | CString15="NO"; |
748 | di << "Shapes with Continuity C0 : " << CString15; |
749 | if(S1_C0 != 0) |
750 | di << " Cases(" << S1_C0 << ") Total shapes(" << S1_C0All << ")" << "\n"; |
751 | else |
752 | di << "\n"; |
7fd59977 |
753 | } |
754 | |
755 | // output for second shape |
756 | di << "\n"; |
757 | di << "Faulties for SECOND shape found : " << FS2 << "\n"; |
758 | if(FS2 != 0) { |
759 | di << "---------------------------------" << "\n"; |
760 | Standard_CString CString7; |
4e57c75e |
761 | if (S2_BadType != 0) |
762 | CString7="YES"; |
763 | else |
764 | CString7="NO"; |
7fd59977 |
765 | di << "Shapes are not suppotrted by BOP: " << CString7 << "\n"; |
766 | Standard_CString CString8; |
4e57c75e |
767 | if (S2_SelfInt != 0) |
768 | CString8="YES"; |
769 | else |
770 | CString8="NO"; |
7fd59977 |
771 | di << "Self-Intersections : " << CString8; |
772 | if(S2_SelfInt != 0) |
773 | di << " Cases(" << S2_SelfInt << ") Total shapes(" << S2_SelfIntAll << ")" << "\n"; |
774 | else |
775 | di << "\n"; |
4e57c75e |
776 | |
777 | Standard_CString CString14; |
778 | if (S2_OpAb != 0) |
779 | CString14="YES"; |
780 | else |
781 | CString14="NO"; |
782 | di << "Check for SI has been aborted : " << CString14 << "\n"; |
7fd59977 |
783 | Standard_CString CString9; |
4e57c75e |
784 | if (S2_SmalE != 0) |
785 | CString9="YES"; |
786 | else |
787 | CString9="NO"; |
7fd59977 |
788 | di << "Too small edges : " << CString9; |
789 | if(S2_SmalE != 0) |
790 | di << " Cases(" << S2_SmalE << ") Total shapes(" << S2_SmalEAll << ")" << "\n"; |
791 | else |
792 | di << "\n"; |
793 | Standard_CString CString10; |
4e57c75e |
794 | if (S2_BadF != 0) |
795 | CString10="YES"; |
796 | else |
797 | CString10="NO"; |
7fd59977 |
798 | di << "Bad faces : " << CString10; |
799 | if(S2_BadF != 0) |
800 | di << " Cases(" << S2_BadF << ") Total shapes(" << S2_BadFAll << ")" << "\n"; |
801 | else |
802 | di << "\n"; |
803 | Standard_CString CString11; |
4e57c75e |
804 | if (S2_BadV != 0) |
805 | CString11="YES"; |
806 | else |
807 | CString11="NO"; |
7fd59977 |
808 | di << "Too close vertices : " << CString11; |
809 | if(S2_BadV != 0) |
810 | di << " Cases(" << S2_BadV << ") Total shapes(" << S2_BadVAll << ")" << "\n"; |
811 | else |
812 | di << "\n"; |
813 | Standard_CString CString12; |
4e57c75e |
814 | if (S2_BadE != 0) |
815 | CString12="YES"; |
816 | else |
817 | CString12="NO"; |
7fd59977 |
818 | di << "Too close edges : " << CString12; |
819 | if(S2_BadE != 0) |
820 | di << " Cases(" << S2_BadE << ") Total shapes(" << S2_BadEAll << ")" << "\n"; |
821 | else |
822 | di << "\n"; |
0e09ee8e |
823 | Standard_CString CString16; |
824 | if (S2_C0 != 0) |
825 | CString16="YES"; |
826 | else |
827 | CString16="NO"; |
828 | di << "Shapes with Continuity C0 : " << CString16; |
829 | if(S2_C0 != 0) |
830 | di << " Cases(" << S2_C0 << ") Total shapes(" << S2_C0All << ")" << "\n"; |
831 | else |
832 | di << "\n"; |
7fd59977 |
833 | |
834 | // warning |
835 | di << "\n"; |
836 | if(hasUnknown) |
837 | di << "WARNING: The unexpected test break occurs!" << "\n"; |
838 | } |
839 | } // full output |
840 | } // has faulties |
841 | |
842 | return 0; |
843 | } |
63def8e6 |
844 | //======================================================================= |
845 | //function : MakeShapeForFullOutput |
846 | //purpose : |
847 | //======================================================================= |
848 | void MakeShapeForFullOutput (const TCollection_AsciiString & aBaseName, |
849 | const Standard_Integer aIndex, |
850 | const BOPCol_ListOfShape & aList, |
851 | Standard_Integer& aCount, |
852 | Draw_Interpretor& di) |
853 | { |
854 | TCollection_AsciiString aNum(aIndex); |
855 | TCollection_AsciiString aName = aBaseName + aNum; |
856 | Standard_CString name = aName.ToCString(); |
857 | |
858 | TopoDS_Compound cmp; |
859 | BRep_Builder BB; |
860 | BB.MakeCompound(cmp); |
861 | |
862 | BOPCol_ListIteratorOfListOfShape anIt(aList); |
863 | for(; anIt.More(); anIt.Next()) { |
864 | const TopoDS_Shape & aS = anIt.Value(); |
865 | BB.Add(cmp, aS); |
866 | aCount++; |
867 | } |
868 | di << "Made faulty shape: " << name << "\n"; |
869 | DBRep::Set(name, cmp); |
870 | } |