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