0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / BOPAlgo / BOPAlgo_ArgumentAnalyzer.cxx
CommitLineData
4e57c75e 1// Created on: 2004-09-02
973c2be1 2// Copyright (c) 2004-2014 OPEN CASCADE SAS
4e57c75e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
4e57c75e 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.
4e57c75e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
4e57c75e 14
42cf5bc1 15#include <BOPAlgo_ArgumentAnalyzer.hxx>
16#include <BOPAlgo_BuilderFace.hxx>
17#include <BOPAlgo_CheckerSI.hxx>
18#include <BOPAlgo_Operation.hxx>
19#include <BOPCol_ListOfShape.hxx>
20#include <BOPCol_MapOfShape.hxx>
319da2e4 21#include <BOPCol_IndexedMapOfShape.hxx>
42cf5bc1 22#include <BOPCol_SequenceOfShape.hxx>
23#include <BOPDS_DS.hxx>
24#include <BOPDS_MapOfPassKey.hxx>
25#include <BOPTools.hxx>
26#include <BOPTools_AlgoTools.hxx>
27#include <BOPTools_AlgoTools3D.hxx>
28#include <BRep_Builder.hxx>
29#include <BRep_TEdge.hxx>
30#include <BRep_TFace.hxx>
31#include <BRep_Tool.hxx>
32#include <BRep_TVertex.hxx>
33#include <BRepExtrema_DistShapeShape.hxx>
34#include <Geom_Surface.hxx>
35#include <gp_Pnt.hxx>
36#include <IntTools_CommonPrt.hxx>
37#include <IntTools_Context.hxx>
38#include <IntTools_EdgeEdge.hxx>
39#include <IntTools_Range.hxx>
4e57c75e 40#include <Standard_ErrorHandler.hxx>
41#include <Standard_Failure.hxx>
63def8e6 42#include <TColStd_Array2OfBoolean.hxx>
42cf5bc1 43#include <TopExp.hxx>
44#include <TopExp_Explorer.hxx>
4e57c75e 45#include <TopoDS.hxx>
4e57c75e 46#include <TopoDS_Edge.hxx>
42cf5bc1 47#include <TopoDS_Iterator.hxx>
48#include <TopoDS_Shape.hxx>
4e57c75e 49#include <TopoDS_Shell.hxx>
50#include <TopoDS_Solid.hxx>
42cf5bc1 51#include <TopoDS_Vertex.hxx>
52#include <TopoDS_Wire.hxx>
4e57c75e 53// ================================================================================
54// function: Constructor
55// purpose:
56// ================================================================================
57BOPAlgo_ArgumentAnalyzer::BOPAlgo_ArgumentAnalyzer() :
b1d15f53 58BOPAlgo_Algo(),
4e57c75e 59myStopOnFirst(Standard_False),
60myOperation(BOPAlgo_UNKNOWN),
61myArgumentTypeMode(Standard_False),
62mySelfInterMode(Standard_False),
63mySmallEdgeMode(Standard_False),
64myRebuildFaceMode(Standard_False),
65myTangentMode(Standard_False),
66myMergeVertexMode(Standard_False),
67myMergeEdgeMode(Standard_False),
0e09ee8e 68myContinuityMode(Standard_False),
e98e3990 69myCurveOnSurfaceMode(Standard_False),
4e57c75e 70myEmpty1(Standard_False),
b1d15f53 71myEmpty2(Standard_False),
72myFuzzyValue(0.)
4e57c75e 73{
74}
b1d15f53 75//=======================================================================
76// function: ~
77// purpose:
78//=======================================================================
79BOPAlgo_ArgumentAnalyzer::~BOPAlgo_ArgumentAnalyzer()
80{
81 myResult.Clear();
82 myToleranceMap.Clear();
83}
4e57c75e 84
85// ================================================================================
86// function: SetShape1
87// purpose:
88// ================================================================================
89void BOPAlgo_ArgumentAnalyzer::SetShape1(const TopoDS_Shape & TheShape)
90{
91 myShape1 = TheShape;
92}
93
94// ================================================================================
95// function: SetShape2
96// purpose:
97// ================================================================================
98void BOPAlgo_ArgumentAnalyzer::SetShape2(const TopoDS_Shape & TheShape)
99{
100 myShape2 = TheShape;
101}
102
103// ================================================================================
104// function: GetShape1
105// purpose:
106// ================================================================================
107const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape1() const
108{
109 return myShape1;
110}
111
112// ================================================================================
113// function: GetShape2
114// purpose:
115// ================================================================================
116const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape2() const
117{
118 return myShape2;
119}
120
121// ================================================================================
122// function: OperationType
123// purpose:
124// ================================================================================
125BOPAlgo_Operation& BOPAlgo_ArgumentAnalyzer::OperationType()
126{
127 return myOperation;
128}
129
130// ================================================================================
131// function: StopOnFirstFaulty
132// purpose:
133// ================================================================================
134Standard_Boolean & BOPAlgo_ArgumentAnalyzer::StopOnFirstFaulty()
135{
136 return myStopOnFirst;
137}
138
139// ================================================================================
140// function: Prepare
141// purpose:
142// ================================================================================
143void BOPAlgo_ArgumentAnalyzer::Prepare()
144{
145 Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
146 if (!isS1) {
147 myEmpty1 = BOPTools_AlgoTools3D::IsEmptyShape(myShape1);
148 }
149 if (!isS2) {
150 myEmpty2 = BOPTools_AlgoTools3D::IsEmptyShape(myShape2);
151 }
152}
153// ================================================================================
154// function: Perform
155// purpose:
156// ================================================================================
157void BOPAlgo_ArgumentAnalyzer::Perform()
158{
159 try {
160 OCC_CATCH_SIGNALS
161 myResult.Clear();
b1d15f53 162 //
163 UserBreak();
164 //
165 // 1. Prepare
4e57c75e 166 Prepare();
b1d15f53 167 //
168 UserBreak();
169 //
170 // 2. Update Tolerances according to myFuzzyValue
171 UpdateTolerances();
172 //
173 UserBreak();
174 //
175 // 3. Test types
4e57c75e 176 if(myArgumentTypeMode) {
177 TestTypes();
178 }
b1d15f53 179 //
180 UserBreak();
181 //
182 // 4. Test self-interference
4e57c75e 183 if(mySelfInterMode) {
184 TestSelfInterferences();
185 }
b1d15f53 186 //
187 UserBreak();
188 //
189 // 5. Test small edges
4e57c75e 190 if(mySmallEdgeMode) {
191 if(!(!myResult.IsEmpty() && myStopOnFirst))
192 TestSmallEdge();
193 }
b1d15f53 194 //
195 UserBreak();
196 //
197 // 6. Test possibility to rebuild faces
4e57c75e 198 if(myRebuildFaceMode) {
199 if(!(!myResult.IsEmpty() && myStopOnFirst))
200 TestRebuildFace();
201 }
b1d15f53 202 //
203 UserBreak();
204 //
205 // 7. Test tangent
4e57c75e 206 if(myTangentMode) {
207 if(!(!myResult.IsEmpty() && myStopOnFirst))
208 TestTangent();
209 }
b1d15f53 210 //
211 UserBreak();
212 //
213 // 8. Test merge vertices
4e57c75e 214 if(myMergeVertexMode) {
215 if(!(!myResult.IsEmpty() && myStopOnFirst))
216 TestMergeVertex();
217 }
b1d15f53 218 //
219 UserBreak();
220 //
221 // 9. Test merge edges
4e57c75e 222 if(myMergeEdgeMode) {
223 if(!(!myResult.IsEmpty() && myStopOnFirst))
224 TestMergeEdge();
225 }
b1d15f53 226 //
227 UserBreak();
228 //
229 // 10. Test shapes continuity
0e09ee8e 230 if(myContinuityMode) {
231 if(!(!myResult.IsEmpty() && myStopOnFirst))
232 TestContinuity();
233 }
b1d15f53 234 //
235 UserBreak();
236 //
237 // 11. Test validity of the curves on the surfaces
e98e3990 238 if(myCurveOnSurfaceMode) {
239 if(!(!myResult.IsEmpty() && myStopOnFirst))
240 TestCurveOnSurface();
241 }
4e57c75e 242 }
243 catch(Standard_Failure) {
244 BOPAlgo_CheckResult aResult;
245 aResult.SetCheckStatus(BOPAlgo_CheckUnknown);
246 myResult.Append(aResult);
247 }
b1d15f53 248 //
249 SetDefaultTolerances();
4e57c75e 250}
251
252// ================================================================================
253// function: HasFaulty
254// purpose:
255// ================================================================================
256Standard_Boolean BOPAlgo_ArgumentAnalyzer::HasFaulty() const
257{
258 return ( !myResult.IsEmpty());
259}
260
261// ================================================================================
262// function: GetCheckResult
263// purpose:
264// ================================================================================
265const BOPAlgo_ListOfCheckResult& BOPAlgo_ArgumentAnalyzer::GetCheckResult() const
266{
267 return myResult;
268}
269
270// ================================================================================
271// function: TestTypes
272// purpose:
273// ================================================================================
274void BOPAlgo_ArgumentAnalyzer::TestTypes()
275{
276 Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull();
277
278 if(isS1 && isS2) {
279 BOPAlgo_CheckResult aResult;
280 aResult.SetCheckStatus(BOPAlgo_BadType);
281 myResult.Append(aResult);
282 return;
283 }
284
285 //single shape check
286 if((isS1 && !isS2) || (!isS1 && isS2)) {
287 Standard_Boolean bIsEmpty = (isS1) ? myEmpty2 : myEmpty1;
288
289 if(bIsEmpty || myOperation!=BOPAlgo_UNKNOWN) {
290 const TopoDS_Shape & aS = (isS1) ? myShape2 : myShape1;
291 BOPAlgo_CheckResult aResult;
292 aResult.SetShape1(aS);
293 aResult.SetCheckStatus(BOPAlgo_BadType);
294 myResult.Append(aResult);
295 return;
296 }
297 }
298 // two shapes check (begin)
299 else {
300 if(myEmpty1 || myEmpty2) {
301 BOPAlgo_CheckResult aResult;
302 if(myEmpty1 && myEmpty2) {
303 aResult.SetShape1(myShape1);
304 aResult.SetShape2(myShape2);
305 }
306 else {
307 const TopoDS_Shape & aS = myEmpty1 ? myShape1 : myShape2;
308 if(myEmpty1)
309 aResult.SetShape1(aS);
310 else
311 aResult.SetShape2(aS);
312 }
313 aResult.SetCheckStatus(BOPAlgo_BadType);
314 myResult.Append(aResult);
315 return;
316 }
317 //
318 Standard_Integer aDim1, aDim2;
319 Standard_Boolean bBadTypes = Standard_False;
320 //
321 aDim1 = BOPTools_AlgoTools::Dimension(myShape1);
322 aDim2 = BOPTools_AlgoTools::Dimension(myShape2);
323 if (aDim1 < aDim2) {
324 if (myOperation == BOPAlgo_FUSE ||
325 myOperation == BOPAlgo_CUT21) {
326 bBadTypes = Standard_True;
327 }
328 }
329 else if (aDim1 > aDim2) {
330 if (myOperation == BOPAlgo_FUSE ||
331 myOperation == BOPAlgo_CUT) {
332 bBadTypes = Standard_True;
333 }
334 }
335 if (bBadTypes) {
336 BOPAlgo_CheckResult aResult;
337 aResult.SetShape1(myShape1);
338 aResult.SetShape2(myShape2);
339 aResult.SetCheckStatus(BOPAlgo_BadType);
340 myResult.Append(aResult);
341 }
342 }
343}
ceaa5e27 344//=======================================================================
345//function : TestSelfInterferences
346//purpose :
347//=======================================================================
4e57c75e 348void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
349{
63def8e6 350 Standard_Integer ii;
351 //
4e57c75e 352 for(ii = 0; ii < 2; ii++) {
9d1c5188 353 const TopoDS_Shape& aS = (ii == 0) ? myShape1 : myShape2;
ceaa5e27 354 if(aS.IsNull()) {
4e57c75e 355 continue;
ceaa5e27 356 }
63def8e6 357 //
4e57c75e 358 Standard_Boolean bIsEmpty = (ii == 0) ? myEmpty1 : myEmpty2;
359 if (bIsEmpty) {
360 continue;
361 }
63def8e6 362 //
363 Standard_Integer iErr, n1, n2;
364 BOPDS_MapIteratorMapOfPassKey aItMPK;
4e57c75e 365 BOPCol_ListOfShape anArgs;
63def8e6 366 BOPAlgo_CheckerSI aChecker;
ceaa5e27 367 //
4e57c75e 368 anArgs.Append(aS);
369 aChecker.SetArguments(anArgs);
a967f104 370 aChecker.SetNonDestructive(Standard_True);
b1d15f53 371 aChecker.SetRunParallel(myRunParallel);
372 aChecker.SetProgressIndicator(myProgressIndicator);
4e57c75e 373 //
374 aChecker.Perform();
63def8e6 375 iErr=aChecker.ErrorStatus();
4e57c75e 376 //
63def8e6 377 const BOPDS_DS& aDS=*(aChecker.PDS());
378 const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
80db5701 379 //
63def8e6 380 aItMPK.Initialize(aMPK);
381 for (; aItMPK.More(); aItMPK.Next()) {
382 const BOPDS_PassKey& aPK=aItMPK.Value();
383 aPK.Ids(n1, n2);
384 if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
385 continue;
386 }
387 //
388 const TopoDS_Shape& aS1=aDS.Shape(n1);
389 const TopoDS_Shape& aS2=aDS.Shape(n2);
390 //
391 BOPAlgo_CheckResult aResult;
392 if(ii == 0) {
393 aResult.SetShape1(myShape1);
394 aResult.AddFaultyShape1(aS1);
395 aResult.AddFaultyShape1(aS2);
4e57c75e 396 }
63def8e6 397 else {
398 aResult.SetShape2(myShape2);
399 aResult.AddFaultyShape2(aS1);
400 aResult.AddFaultyShape2(aS2);
401 }
402 aResult.SetCheckStatus(BOPAlgo_SelfIntersect);
403 myResult.Append(aResult);
4e57c75e 404 }
ceaa5e27 405 //
4e57c75e 406 if (iErr) {
407 BOPAlgo_CheckResult aResult;
4e57c75e 408 if(ii == 0) {
0e09ee8e 409 aResult.SetShape1(myShape1);
4e57c75e 410 aResult.AddFaultyShape1(myShape1);
411 }
412 else {
0e09ee8e 413 aResult.SetShape2(myShape2);
4e57c75e 414 aResult.AddFaultyShape2(myShape2);
415 }
416 aResult.SetCheckStatus(BOPAlgo_OperationAborted);
417 myResult.Append(aResult);
418 }
63def8e6 419 }// for(ii = 0; ii < 2; ii++) {
4e57c75e 420}
4e57c75e 421// ================================================================================
422// function: TestSmallEdge
423// purpose:
424// ================================================================================
425void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
426{
427 Standard_Integer i = 0;
428 BRepExtrema_DistShapeShape aDist;
1e143abb 429 Handle(IntTools_Context) aCtx;
4e57c75e 430 //
1e143abb 431 aCtx = new IntTools_Context;
4e57c75e 432
433 for(i = 0; i < 2; i++) {
9d1c5188 434 const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
4e57c75e 435
436 if(aS.IsNull())
437 continue;
438
439 TopExp_Explorer anExp(aS, TopAbs_EDGE);
440
441 for(; anExp.More(); anExp.Next()) {
9d1c5188 442 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&anExp.Current();
443 if (BRep_Tool::Degenerated(anEdge)) {
444 continue;
445 }
4e57c75e 446
447 if(BOPTools_AlgoTools::IsMicroEdge(anEdge, aCtx)) {
448 Standard_Boolean bKeepResult = Standard_True;
449
450 if(myOperation == BOPAlgo_SECTION) {
9d1c5188 451 const TopoDS_Shape& anOtherS = (i == 0) ? myShape2 : myShape1;
4e57c75e 452
453 if(!anOtherS.IsNull()) {
454 aDist.LoadS2(anOtherS);
455
456 Standard_Boolean bVertexIsOnShape = Standard_False;
457 Standard_Integer ii = 0;
458 TopExp_Explorer anExpV(anEdge, TopAbs_VERTEX);
459
460 for(; anExpV.More(); anExpV.Next()) {
9d1c5188 461 const TopoDS_Shape& aV = anExpV.Current();
4e57c75e 462
463 aDist.LoadS1(aV);
464 aDist.Perform();
465
466 if(aDist.IsDone()) {
467
468 for(ii = 1; ii <= aDist.NbSolution(); ii++) {
9d1c5188 469 Standard_Real aTolerance = BRep_Tool::Tolerance(*(TopoDS_Vertex*)&aV);
470 const TopoDS_Shape& aSupportShape = aDist.SupportOnShape2(ii);
4e57c75e 471
472 switch(aSupportShape.ShapeType()) {
473 case TopAbs_VERTEX: {
9d1c5188 474 aTolerance += BRep_Tool::Tolerance(*(TopoDS_Vertex*)&(aSupportShape));
4e57c75e 475 break;
476 }
477 case TopAbs_EDGE: {
9d1c5188 478 aTolerance += BRep_Tool::Tolerance(*(TopoDS_Edge*)&(aSupportShape));
4e57c75e 479 break;
480 }
481 case TopAbs_FACE: {
9d1c5188 482 aTolerance += BRep_Tool::Tolerance(*(TopoDS_Face*)&(aSupportShape));
4e57c75e 483 break;
484 }
485 default:
486 break;
487 }
488
489 if(aDist.Value() < aTolerance) {
490 bVertexIsOnShape = Standard_True;
491 break;
492 }
493 }
494 }
495 }
496
497 if(!bVertexIsOnShape) {
498 bKeepResult = Standard_False;
499 }
500 }
501 }
502
503 if(bKeepResult) {
504 BOPAlgo_CheckResult aResult;
505
506 if(i == 0) {
507 aResult.SetShape1(myShape1);
508 aResult.AddFaultyShape1(anEdge);
509 }
510 else {
511 aResult.SetShape2(myShape2);
512 aResult.AddFaultyShape2(anEdge);
513 }
514
515 aResult.SetCheckStatus(BOPAlgo_TooSmallEdge);
516 myResult.Append(aResult);
517
518 if(myStopOnFirst) {
519 return;
520 }
521 }
522 }
523 }
524 }
525}
4e57c75e 526// ================================================================================
527// function: TestRebuildFace
528// purpose:
529// ================================================================================
530void BOPAlgo_ArgumentAnalyzer::TestRebuildFace()
531{
532 if((myOperation == BOPAlgo_SECTION) ||
533 (myOperation == BOPAlgo_UNKNOWN))
534 return;
535 Standard_Integer i = 0;
536
537 for(i = 0; i < 2; i++) {
9d1c5188 538 const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
4e57c75e 539
540 if(aS.IsNull())
541 continue;
542
543 TopExp_Explorer anExp(aS, TopAbs_FACE);
544 BOPCol_ListOfShape aLS;
545
546 for(; anExp.More(); anExp.Next()) {
9d1c5188 547 const TopoDS_Face& aFace = *(TopoDS_Face*)&(anExp.Current());
4e57c75e 548
549 TopoDS_Face aFF = aFace;
550 aFF.Orientation(TopAbs_FORWARD);
551 TopExp_Explorer anExpE(aFF, TopAbs_EDGE);
552 Standard_Integer nbstartedges = 0;
553 aLS.Clear();
554 //
555 for(; anExpE.More(); anExpE.Next()) {
556 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&anExpE.Current()));
557 TopAbs_Orientation anOriE=aE.Orientation();
558 //
559 if (anOriE==TopAbs_INTERNAL) {
560 TopoDS_Edge aEE=aE;
561 aEE.Orientation(TopAbs_FORWARD);
562 aLS.Append(aEE);
563 aEE.Orientation(TopAbs_REVERSED);
564 aLS.Append(aEE);
565 }
566 else {
567 aLS.Append(aE);
568 }
569 nbstartedges++;
570 }
571 BOPAlgo_BuilderFace aBF;
572 aBF.SetFace(aFace);
573 aBF.SetShapes(aLS);
574 aBF.Perform();
575 const BOPCol_ListOfShape& aLF = aBF.Areas();
576 Standard_Boolean bBadFace = Standard_False;
577
578 if(aLF.Extent() != 1) {
579 bBadFace = Standard_True;
580 }
581 else {
582 Standard_Integer nbedgeused = 0;
583 anExpE.Init(aLF.First(), TopAbs_EDGE);
584
585 for(; anExpE.More(); anExpE.Next(), nbedgeused++);
586
587 if(nbstartedges != nbedgeused) {
588 bBadFace = Standard_True;
589 }
590 }
591
592 if(bBadFace) {
593 BOPAlgo_CheckResult aResult;
594
595 if(i == 0) {
596 aResult.SetShape1(myShape1);
597 aResult.AddFaultyShape1(aFace);
598 }
599 else {
600 aResult.SetShape2(myShape2);
601 aResult.AddFaultyShape2(aFace);
602 }
603
604 aResult.SetCheckStatus(BOPAlgo_NonRecoverableFace);
605 myResult.Append(aResult);
606
607 if(myStopOnFirst) {
608 return;
609 }
610 }
611 }
612 }
613}
614
615// ================================================================================
616// function: TestTangent
617// purpose:
618// ================================================================================
619void BOPAlgo_ArgumentAnalyzer::TestTangent()
620{
621 // not implemented
622}
623
624// ================================================================================
625// function: TestMergeSubShapes
626// purpose:
627// ================================================================================
628 void BOPAlgo_ArgumentAnalyzer::TestMergeSubShapes(const TopAbs_ShapeEnum theType)
629{
630 if(myShape1.IsNull() || myShape2.IsNull())
631 return;
632
633 if (myEmpty1 || myEmpty2)
634 return;
635
636 BOPAlgo_CheckStatus aStatus = BOPAlgo_CheckUnknown;
637
638 switch(theType) {
639 case TopAbs_VERTEX: {
640 aStatus = BOPAlgo_IncompatibilityOfVertex;
641 break;
642 }
643 case TopAbs_EDGE: {
644 aStatus = BOPAlgo_IncompatibilityOfEdge;
645 break;
646 }
647 case TopAbs_FACE: {
648 aStatus = BOPAlgo_IncompatibilityOfFace;
649 break;
650 }
651 default:
652 return;
653 }
654 TopExp_Explorer anExp1(myShape1, theType);
655 TopExp_Explorer anExp2(myShape2, theType);
656 BOPCol_SequenceOfShape aSeq1, aSeq2;
657 BOPCol_MapOfShape aMap1, aMap2;
658
659 for(; anExp1.More(); anExp1.Next()) {
9d1c5188 660 const TopoDS_Shape& aS1 = anExp1.Current();
4e57c75e 661
662 if(aMap1.Contains(aS1))
663 continue;
664 aSeq1.Append(aS1);
665 aMap1.Add(aS1);
666 }
667
668 for(; anExp2.More(); anExp2.Next()) {
9d1c5188 669 const TopoDS_Shape& aS2 = anExp2.Current();
4e57c75e 670 if(aMap2.Contains(aS2))
671 continue;
672 aSeq2.Append(aS2);
673 aMap2.Add(aS2);
674 }
675
676 TColStd_Array2OfBoolean anArrayOfFlag(1, aSeq1.Length(), 1, aSeq2.Length());
677 Standard_Integer i = 0, j = 0;
678 for(i = 1; i <= aSeq1.Length(); i++)
679 for(j = 1; j <= aSeq2.Length(); j++)
680 anArrayOfFlag.SetValue(i, j, Standard_False);
681
682 for(i = 1; i <= aSeq1.Length(); i++) {
9d1c5188 683 const TopoDS_Shape& aS1 = aSeq1.Value(i);
4e57c75e 684 BOPCol_ListOfShape aListOfS2;
685 Standard_Integer nbs = 0;
686
687 for(j = 1; j <= aSeq2.Length(); j++) {
9d1c5188 688 const TopoDS_Shape& aS2 = aSeq2.Value(j);
4e57c75e 689 Standard_Boolean bIsEqual = Standard_False;
690
691 if(theType == TopAbs_VERTEX) {
692
9d1c5188 693 const TopoDS_Vertex& aV1 = *(TopoDS_Vertex*)&(aS1);
694 const TopoDS_Vertex& aV2 = *(TopoDS_Vertex*)&(aS2);
4e57c75e 695 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
696 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
697 Standard_Real aDist = aP1.Distance(aP2);
698
699 if(aDist <= (BRep_Tool::Tolerance(aV1) + BRep_Tool::Tolerance(aV2))) {
700 bIsEqual = Standard_True;
701 }
702 }
703 else if(theType == TopAbs_EDGE) {
9d1c5188 704 const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&(aS1);
705 const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&(aS2);
ec0cdc0e 706 //
707 IntTools_EdgeEdge aEE(aE1, aE2);
708 //
4e57c75e 709 aEE.Perform();
4e57c75e 710 if (aEE.IsDone()) {
711 const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts();
712 Standard_Integer ii = 0;
713
714 for (ii = 1; ii <= aCPrts.Length(); ii++) {
715 const IntTools_CommonPrt& aCPart = aCPrts(ii);
716
717 if (aCPart.Type() == TopAbs_EDGE) {
718 bIsEqual = Standard_True;
719 }
720 }
721 }
722 }
723 else if(theType == TopAbs_FACE) {
724 // not yet implemented!
725 }
726
727 if(bIsEqual) {
728 anArrayOfFlag.SetValue(i, j, Standard_True );
729 aListOfS2.Append(aS2);
730 nbs++;
731 }
732 }
733
734 if(nbs > 1) {
735 BOPAlgo_CheckResult aResult;
736
737 aResult.SetShape1(myShape1);
738 aResult.SetShape2(myShape2);
739 aResult.AddFaultyShape1(aS1);
740 BOPCol_ListIteratorOfListOfShape anIt(aListOfS2);
741
742 for(; anIt.More(); anIt.Next()) {
743 aResult.AddFaultyShape2(anIt.Value());
744 }
745
746 aResult.SetCheckStatus(aStatus);
747 myResult.Append(aResult);
748
749 if(myStopOnFirst) {
750 return;
751 }
752 }
753 }
754
755 for(i = 1; i <= aSeq2.Length(); i++) {
9d1c5188 756 const TopoDS_Shape& aS2 = aSeq2.Value(i);
4e57c75e 757 BOPCol_ListOfShape aListOfS1;
758 Standard_Integer nbs = 0;
759
760 for(j = 1; j <= aSeq1.Length(); j++) {
9d1c5188 761 const TopoDS_Shape& aS1 = aSeq1.Value(j);
4e57c75e 762
763 if(anArrayOfFlag.Value(j, i)) {
764 aListOfS1.Append(aS1);
765 nbs++;
766 }
767 }
768
769 if(nbs > 1) {
770 BOPAlgo_CheckResult aResult;
771
772 aResult.SetShape1(myShape1);
773 aResult.SetShape2(myShape2);
774 BOPCol_ListIteratorOfListOfShape anIt(aListOfS1);
775
776 for(; anIt.More(); anIt.Next()) {
777 aResult.AddFaultyShape1(anIt.Value());
778 }
779 aResult.AddFaultyShape2(aS2);
780
781 aResult.SetCheckStatus(aStatus);
782 myResult.Append(aResult);
783
784 if(myStopOnFirst) {
785 return;
786 }
787 }
788 }
789}
790
791// ================================================================================
792// function: TestMergeVertex
793// purpose:
794// ================================================================================
795void BOPAlgo_ArgumentAnalyzer::TestMergeVertex()
796{
797 TestMergeSubShapes(TopAbs_VERTEX);
798}
799
800// ================================================================================
801// function: TestMergeEdge
802// purpose:
803// ================================================================================
804void BOPAlgo_ArgumentAnalyzer::TestMergeEdge()
805{
806 TestMergeSubShapes(TopAbs_EDGE);
807}
808
0e09ee8e 809// ================================================================================
810// function: TestContinuity
811// purpose:
812// ================================================================================
813void BOPAlgo_ArgumentAnalyzer::TestContinuity()
814{
319da2e4 815 Standard_Integer i, j, aNbS;
0e09ee8e 816 Standard_Real f, l;
817 TopExp_Explorer aExp;
0e09ee8e 818 //
819 for (i = 0; i < 2; ++i) {
820 const TopoDS_Shape& aS = !i ? myShape1 : myShape2;
821 if(aS.IsNull()) {
822 continue;
823 }
824 //
319da2e4 825 BOPCol_IndexedMapOfShape aMS;
0e09ee8e 826 //Edges
827 aExp.Init(aS, TopAbs_EDGE);
828 for (; aExp.More(); aExp.Next()) {
829 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
830 if (BRep_Tool::Degenerated(aE)) {
831 continue;
832 }
833 const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, f, l);
834 if (aC->Continuity() == GeomAbs_C0) {
835 aMS.Add(aE);
836 }
837 }
838 //Faces
839 aExp.Init(aS, TopAbs_FACE);
840 for (; aExp.More(); aExp.Next()) {
841 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
51740958 842 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aF);
843 if (aSurf->Continuity() == GeomAbs_C0) {
0e09ee8e 844 aMS.Add(aF);
845 }
846 }
847 //
848 //add shapes with continuity C0 to result
319da2e4 849 aNbS = aMS.Extent();
850 for (j = 1; j <= aNbS; ++j) {
851 const TopoDS_Shape& aFS = aMS(j);
0e09ee8e 852 BOPAlgo_CheckResult aResult;
853 if(i == 0) {
854 aResult.SetShape1(myShape1);
855 aResult.AddFaultyShape1(aFS);
856 } else {
857 aResult.SetShape2(myShape2);
858 aResult.AddFaultyShape2(aFS);
859 }
860 aResult.SetCheckStatus(BOPAlgo_GeomAbs_C0);
861 myResult.Append(aResult);
862 }
863 }
864}
e98e3990 865
866// ================================================================================
867// function: TestCurveOnSurface
868// purpose:
869// ================================================================================
870void BOPAlgo_ArgumentAnalyzer::TestCurveOnSurface()
871{
872 Standard_Integer i;
873 Standard_Real aT, aD, aTolE;
874 TopExp_Explorer aExpF, aExpE;
875 //
876 for(i = 0; i < 2; i++) {
877 const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
878 if(aS.IsNull()) {
879 continue;
880 }
881 //
882 aExpF.Init(aS, TopAbs_FACE);
883 for (; aExpF.More(); aExpF.Next()) {
884 const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
885 //
886 aExpE.Init(aF, TopAbs_EDGE);
887 for (; aExpE.More(); aExpE.Next()) {
888 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
889 //
890 if (BOPTools_AlgoTools::ComputeTolerance(aF, aE, aD, aT)) {
891 aTolE = BRep_Tool::Tolerance(aE);
892 if (aD > aTolE) {
893 BOPAlgo_CheckResult aResult;
894 aResult.SetCheckStatus(BOPAlgo_InvalidCurveOnSurface);
895 if(i == 0) {
896 aResult.SetShape1(myShape1);
897 aResult.AddFaultyShape1(aE);
898 aResult.AddFaultyShape1(aF);
899 aResult.SetMaxDistance1(aD);
900 aResult.SetMaxParameter1(aT);
901 }
902 else {
903 aResult.SetShape2(myShape2);
904 aResult.AddFaultyShape2(aE);
905 aResult.AddFaultyShape2(aF);
906 aResult.SetMaxDistance2(aD);
907 aResult.SetMaxParameter2(aT);
908 }
909 myResult.Append(aResult);
910 }
911 }
912 }
913 }
914 }
915}
916
b1d15f53 917// ================================================================================
918// function: UpdateTolerances
919// purpose:
920// ================================================================================
921void BOPAlgo_ArgumentAnalyzer::UpdateTolerances()
922{
923 if (myFuzzyValue == 0.) {
924 return;
925 }
926 //
927 BOPCol_MapOfShape aMapShapes;
928 //
929 if (!myShape1.IsNull()) {
930 BOPTools::MapShapes(myShape1, aMapShapes);
931 }
932 if (!myShape2.IsNull()) {
933 BOPTools::MapShapes(myShape2, aMapShapes);
934 }
935 //
936 if (aMapShapes.IsEmpty()) {
937 return;
938 }
939 //
940 Standard_Real aTol, aFuzz;
941 TopAbs_ShapeEnum aType;
942 BOPCol_MapIteratorOfMapOfShape aIt;
943 //
944 aFuzz = myFuzzyValue / 2.;
945 aIt.Initialize(aMapShapes);
946 for (; aIt.More(); aIt.Next()) {
947 const TopoDS_Shape& aS = aIt.Value();
948 aType = aS.ShapeType();
949 //
950 switch (aType) {
951 case TopAbs_VERTEX: {
952 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
953 const Handle(BRep_TVertex)& TV =
954 *((Handle(BRep_TVertex)*)&aV.TShape());
955 aTol = TV->Tolerance();
956 myToleranceMap.Bind(aS, aTol);
957 TV->Tolerance(aTol + aFuzz);
958 break;
959 }
960 case TopAbs_EDGE: {
961 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
962 const Handle(BRep_TEdge)& TE =
963 *((Handle(BRep_TEdge)*)&aE.TShape());
964 aTol = TE->Tolerance();
965 myToleranceMap.Bind(aS, aTol);
966 TE->Tolerance(aTol + aFuzz);
967 break;
968 }
969 case TopAbs_FACE: {
970 const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
971 const Handle(BRep_TFace)& TF =
972 *((Handle(BRep_TFace)*)&aF.TShape());
973 aTol = TF->Tolerance();
974 myToleranceMap.Bind(aS, aTol);
975 TF->Tolerance(aTol + aFuzz);
976 break;
977 }
978 default:
979 break;
980 } // switch (aType) {
981 } // for (; aIt.More(); aIt.Next()) {
982}
983
984// ================================================================================
985// function: SetDefaultTolerances
986// purpose:
987// ================================================================================
988void BOPAlgo_ArgumentAnalyzer::SetDefaultTolerances()
989{
990 if (myFuzzyValue == 0.) {
991 return;
992 }
993 //
994 if (myToleranceMap.IsEmpty()) {
995 return;
996 }
997 //
998 Standard_Real aTol;
999 TopAbs_ShapeEnum aType;
1000 BOPCol_DataMapIteratorOfDataMapOfShapeReal aIt;
1001 //
1002 aIt.Initialize(myToleranceMap);
1003 for (; aIt.More(); aIt.Next()) {
1004 const TopoDS_Shape& aS = aIt.Key();
1005 aTol = aIt.Value();
1006 aType = aS.ShapeType();
1007 //
1008 switch (aType) {
1009 case TopAbs_VERTEX: {
1010 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
1011 const Handle(BRep_TVertex)& TV =
1012 *((Handle(BRep_TVertex)*)&aV.TShape());
1013 TV->Tolerance(aTol);
1014 break;
1015 }
1016 case TopAbs_EDGE: {
1017 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
1018 const Handle(BRep_TEdge)& TE =
1019 *((Handle(BRep_TEdge)*)&aE.TShape());
1020 TE->Tolerance(aTol);
1021 break;
1022 }
1023 case TopAbs_FACE: {
1024 const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
1025 const Handle(BRep_TFace)& TF =
1026 *((Handle(BRep_TFace)*)&aF.TShape());
1027 TF->Tolerance(aTol);
1028 break;
1029 }
1030 default:
1031 break;
1032 } // switch (aType) {
1033 } // for (; aIt.More(); aIt.Next()) {
1034}