1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: NMTTools_PaveFiller_5.cxx
21 // Created: Mon Dec 15 11:28:33 2003
22 // Author: Peter KURNEV
26 #include <NMTTools_PaveFiller.ixx>
28 #include <TColStd_IndexedMapOfInteger.hxx>
30 #include <BRep_Tool.hxx>
31 #include <BRep_Builder.hxx>
33 #include <Bnd_Box.hxx>
35 #include <TopAbs_ShapeEnum.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <TopoDS_Compound.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
45 #include <IntTools_ShrunkRange.hxx>
46 #include <IntTools_Range.hxx>
47 #include <IntTools_EdgeFace.hxx>
48 #include <IntTools_PContext.hxx>
49 #include <IntTools_SequenceOfCommonPrts.hxx>
50 #include <IntTools_CommonPrt.hxx>
51 #include <IntTools_Tools.hxx>
53 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
54 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
55 #include <BooleanOperations_OnceExplorer.hxx>
57 #include <BOPTools_Tools.hxx>
58 #include <BOPTools_Pave.hxx>
59 #include <BOPTools_PaveSet.hxx>
60 #include <BOPTools_ListOfPave.hxx>
61 #include <BOPTools_ListIteratorOfListOfPave.hxx>
62 #include <BOPTools_PaveBlock.hxx>
63 #include <BOPTools_ListOfPaveBlock.hxx>
64 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
65 #include <BOPTools_ESInterference.hxx>
66 #include <BOPTools_InterferencePool.hxx>
67 #include <BOPTools_CArray1OfVVInterference.hxx>
68 #include <BOPTools_CArray1OfESInterference.hxx>
69 #include <BOPTools_VVInterference.hxx>
70 #include <BOPTools_ESInterference.hxx>
71 #include <BOPTools_IDMapOfPaveBlockIMapOfInteger.hxx>
72 #include <BOPTools_IMapOfPaveBlock.hxx>
74 #include <NMTDS_ShapesDataStructure.hxx>
76 #include <NMTTools_ListOfCommonBlock.hxx>
77 #include <NMTTools_CommonBlockAPI.hxx>
78 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
79 #include <NMTTools_CommonBlockAPI.hxx>
80 #include <NMTTools_ListOfCommonBlock.hxx>
83 void VertexParameter(const IntTools_CommonPrt& aCPart,
86 Standard_Boolean IsOnPave(const Standard_Real& aTR,
87 const IntTools_Range& aCPRange,
88 const Standard_Real& aTolerance);
90 //=======================================================================
91 // function: PerformEF
93 //=======================================================================
94 void NMTTools_PaveFiller::PerformEF()
96 myIsDone=Standard_False;
98 Standard_Integer n1, n2, anIndexIn=0, nE, nF, aNbEFs, aBlockLength;
99 Standard_Boolean bJustAdd;
100 Standard_Real aTolE, aTolF, aDeflection=0.01;
101 Standard_Integer aDiscretize=35;
102 BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
103 BOPTools_IDMapOfPaveBlockIMapOfInteger aMapCB;
104 BOPTools_IMapOfPaveBlock aIMPBx;
107 BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
109 myDSIt.Initialize(TopAbs_EDGE, TopAbs_FACE);
111 // BlockLength correction
112 aNbEFs=ExpectedPoolLength();
113 aBlockLength=aEFs.BlockLength();
114 if (aNbEFs > aBlockLength) {
115 aEFs.SetBlockLength(aNbEFs);
118 for (; myDSIt.More(); myDSIt.Next()) {
119 myDSIt.Current(n1, n2, bJustAdd);
122 if (myIntrPool->IsComputed(n1, n2)) {
130 // all Common Blocks for face nF
132 NMTTools_ListOfCommonBlock aLCBF;
133 CommonBlocksFace(nF, aLCBF);
134 NMTTools_CommonBlockAPI aCBAPIF(aLCBF);
137 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
141 const TopoDS_Edge aE=TopoDS::Edge(myDS->GetShape(nE));
142 if (BRep_Tool::Degenerated(aE)){
145 aTolE=BRep_Tool::Tolerance(aE);
147 const TopoDS_Face aF=TopoDS::Face(myDS->GetShape(nF));
148 aTolF=BRep_Tool::Tolerance(aF);
149 const Bnd_Box& aBBF=myDS->GetBoundingBox(nF);
151 // Process each PaveBlock on edge nE
152 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
154 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
155 for (; anIt.More(); anIt.Next()) {
156 BOPTools_PaveBlock& aPB=anIt.Value();
158 if (aCBAPIF.IsCommonBlock(aPB)) {
162 const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
163 const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
164 const Bnd_Box& aBBE=aShrunkRange.BndBox();
166 if (aBBF.IsOut (aBBE)) {
171 IntTools_EdgeFace aEF;
176 aEF.SetDiscretize (aDiscretize);
177 aEF.SetDeflection (aDeflection);
179 aEF.SetContext((IntTools_PContext)&myContext);
181 IntTools_Range anewSR = aSR;
183 // Correction of the Shrunk Range
184 BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
185 aEF.SetRange (anewSR);
190 const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
191 Standard_Integer i, aNbCPrts;
192 aNbCPrts=aCPrts.Length();
193 for (i=1; i<=aNbCPrts; i++) {
197 const IntTools_CommonPrt& aCPart=aCPrts(i);
198 TopAbs_ShapeEnum aType=aCPart.Type();
201 case TopAbs_VERTEX: {
202 Standard_Boolean bIsOnPave1, bIsOnPave2;
203 Standard_Integer nVF;
204 Standard_Real aT, aTolToDecide;
205 TopoDS_Vertex aNewVertex;
207 const IntTools_Range& aR=aCPart.Range1();
210 VertexParameter(aCPart, aT);
211 BOPTools_Tools::MakeNewVertex(aE, aT, aF, aNewVertex);
213 //decide to add pave or not
216 bIsOnPave1=IsOnPave(anewSR.First(), aR, aTolToDecide);
217 bIsOnPave2=IsOnPave(anewSR.Last() , aR, aTolToDecide);
219 if (!bIsOnPave1 && !bIsOnPave2) {
220 nVF=CheckFacePaves(aNewVertex, nF);
223 // Add Interference to the Pool
224 BOPTools_ESInterference anInterf (nE, nF, aCPart);
225 anIndexIn=aEFs.Append(anInterf);
226 anInterf.SetNewShape(0);
228 aMapVI.Add(aNewVertex, anIndexIn);
232 }// if (!bIsOnPave1 && !bIsOnPave2)
233 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
234 }// case TopAbs_VERTEX:
238 Standard_Boolean aCoinsideFlag;
240 aCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
241 if (!aCoinsideFlag) {
242 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
247 if (aMapCB.Contains(aPB)) {
248 TColStd_IndexedMapOfInteger& aMapF=aMapCB.ChangeFromKey(aPB);
252 TColStd_IndexedMapOfInteger aMapF;
254 aMapCB.Add(aPB, aMapF);
256 //modified by NIZNHY-PKV Fri Jan 23 14:13:08 2004 f
258 //modified by NIZNHY-PKV Fri Jan 23 14:13:10 2004 t
259 }// case TopAbs_EDGE:
265 } // for (i=1; i<=aNbCPrts; i++)
266 } //if (aEF.IsDone())
267 } // for (; anIt.More(); anIt.Next())
268 }// for (; myDSIt.More(); myDSIt.Next())
270 // Treat New vertices
271 EFNewVertices(aMapVI);
273 // Add draft Common Blocks of EF type
274 EFCommonBlocks(aMapCB);
276 // Collect all CB we suspected to split by new vertices
277 NMTTools_ListOfCommonBlock aLCBx;
279 Standard_Integer i, aNbPBx, nEx;
280 BOPTools_IMapOfPaveBlock aMx;
282 aNbPBx=aIMPBx.Extent();
283 for (i=1; i<=aNbPBx; ++i) {
284 const BOPTools_PaveBlock& aPBx=aIMPBx(i);
285 nEx=aPBx.OriginalEdge();
286 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nEx));
288 NMTTools_CommonBlockAPI aCBAPIx(aLCB);
289 if (aCBAPIx.IsCommonBlock(aPBx)) {
290 NMTTools_CommonBlock& aCBx=aCBAPIx.CommonBlock(aPBx);
291 const BOPTools_PaveBlock& aPB1=aCBx.PaveBlock1();
292 if (!aMx.Contains(aPB1)){
301 // Split the common blocks above
302 if (aLCBx.Extent()) {
303 ReplaceCommonBlocks(aLCBx);
306 myIsDone=Standard_True;
308 //=======================================================================
309 // function:EFCommonBlocks
311 //=======================================================================
312 void NMTTools_PaveFiller::EFCommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfInteger& aMapCB)
314 Standard_Integer i, aNbPB, nE, j, aNbF, nF;
316 aNbPB=aMapCB.Extent();
318 for (i=1; i<=aNbPB; ++i) {
319 const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
320 const TColStd_IndexedMapOfInteger& aMapF=aMapCB.FindFromIndex(i);
323 nE=aPB.OriginalEdge();
325 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
327 NMTTools_CommonBlockAPI aCBAPI(aLCB);
328 if (aCBAPI.IsCommonBlock(aPB)) {
329 NMTTools_CommonBlock& aCB=aCBAPI.CommonBlock(aPB);
330 for (j=1; j<=aNbF; ++j) {
336 NMTTools_CommonBlock aCB;
338 aCB.AddPaveBlock(aPB);
339 for (j=1; j<=aNbF; ++j) {
347 //=======================================================================
348 // function:EFNewVertices
350 //=======================================================================
351 void NMTTools_PaveFiller::EFNewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
353 Standard_Integer i, j, aNb, aNewShape, aFlag, iX, aNbVV, aNbSimple;
354 Standard_Integer aWhat, aWith, nE, nF, nV, aNbIEF, aNbEdges;
356 TopoDS_Compound aCompound;
357 TopoDS_Vertex aNewVertex;
360 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEF;
361 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
362 TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
364 BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
368 if (!aNb) { // no new vertices, no new problems
374 aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
375 EFNewVertices(aNewVertex, aMapVI);
379 // 1. Make compound from new vertices
380 aBB.MakeCompound(aCompound);
381 for (i=1; i<=aNb; ++i) {
382 const TopoDS_Shape& aV=aMapVI.FindKey(i);
383 aBB.Add(aCompound, aV);
386 // 2. VV intersection between these vertices
387 // using the auxiliary Filler
388 NMTDS_ShapesDataStructure tDS;
390 tDS.SetCompositeShape(aCompound);
393 BOPTools_InterferencePool tInterfPool(tDS);
394 NMTTools_PaveFiller tPaveFiller(tInterfPool);
398 tPaveFiller.PerformVV();
399 tPaveFiller.PerformNewVertices();
401 const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
403 // 3. Separate Comlex and Simple new vertices
404 aNbVV=aVVInterfs.Extent();
405 for (i=1; i<=aNbVV; ++i) {
406 const BOPTools_VVInterference& aVV=aVVInterfs(i);
407 aVV.Indices(aWhat, aWith);
408 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
409 const TopoDS_Shape& aV2=tDS.Shape(aWith);
410 aMNVComplex.Add(aV1);
411 aMNVComplex.Add(aV2);
414 for (i=1; i<=aNb; ++i) {
415 const TopoDS_Shape& aV=aMapVI.FindKey(i);
416 if (!aMNVComplex.Contains(aV)) {
421 // 4. Treat Simple new Vertices
422 aNbSimple=aMNVSimple.Extent();
423 for (i=1; i<=aNbSimple; ++i) {
424 const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
425 EFNewVertices(aV, aMapVI);
428 // 3. Fill Maps : NewVertex-edges (aMNVE)
429 // NewVertex-interferences (aMNVIEE)
430 aNb=aVVInterfs.Extent();
431 for (i=1; i<=aNb; ++i) {
432 const BOPTools_VVInterference& aVV=aVVInterfs(i);
433 aNewShape=aVV.NewShape();
438 if (!aMNVE.Contains(aNewShape)) {
439 TColStd_IndexedMapOfInteger aMx;
440 aMNVE.Add(aNewShape, aMx);
442 if (!aMNVIEF.Contains(aNewShape)) {
443 TColStd_IndexedMapOfInteger aMx;
444 aMNVIEF.Add(aNewShape, aMx);
447 TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
448 TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.ChangeFromKey(aNewShape);
450 aVV.Indices(aWhat, aWith);
452 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
453 iX=aMapVI.FindFromKey(aV1);
454 const BOPTools_ESInterference& aEF1=aEFs(iX);
455 aEF1.Indices(nE, nF);
460 const TopoDS_Shape& aV2=tDS.Shape(aWith);
461 iX=aMapVI.FindFromKey(aV2);
462 const BOPTools_ESInterference& aEF2=aEFs(iX);
463 aEF2.Indices(nE, nF);
468 // 4. Process new vertices
470 for (i=1; i<=aNb; ++i) { // xx
474 aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
476 // Insert New Vertex in DS;
477 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
478 aNewShape=myDS->NumberOfInsertedShapes();
479 myDS->SetState (aNewShape, BooleanOperations_ON);
481 // Update index of NewShape in EF interferences
482 const TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.FindFromKey(nV);
483 aNbIEF=aMIEF.Extent();
484 for (j=1; j<=aNbIEF; ++j) {
486 BOPTools_ESInterference& aEF=aEFs(iX);
487 aEF.SetNewShape(aNewShape);
490 // Update Paves on all edges
491 const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
492 aNbEdges=aME.Extent();
493 for (j=1; j<=aNbEdges; ++j) {
495 const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));
497 aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
500 aPave.SetInterference(-1);
501 aPave.SetType (BooleanOperations_EdgeSurface);
502 aPave.SetIndex(aNewShape);
505 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
506 aPaveSet.Append(aPave);
511 //=======================================================================
512 // function:EFNewVertices
514 //=======================================================================
515 void NMTTools_PaveFiller::EFNewVertices (const TopoDS_Vertex& aNewVertex,
516 const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
518 Standard_Integer i, aNewShape, nE, nF;
521 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
523 BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
525 // Insert New Vertex in DS;
526 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
527 aNewShape=myDS->NumberOfInsertedShapes();
528 myDS->SetState (aNewShape, BooleanOperations_ON);
529 // Insert New Vertex in EFInterference
530 i=aMapVI.FindFromKey(aNewVertex);
531 BOPTools_ESInterference& aEFInterf= aEFs(i);
532 aEFInterf.SetNewShape(aNewShape);
533 // Extract interference info
534 aEFInterf.Indices(nE, nF);
536 const IntTools_CommonPrt& aCPart=aEFInterf.CommonPrt();
537 VertexParameter(aCPart, aT);
540 aPave.SetInterference(i);
541 aPave.SetType (BooleanOperations_EdgeSurface);
542 aPave.SetIndex(aNewShape);
544 // Append the Pave to the myPavePoolNew
545 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
546 aPaveSet.Append(aPave);
549 //=======================================================================
550 // function: CheckFacePaves
552 //=======================================================================
553 Standard_Integer NMTTools_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aNewVertex,
554 const Standard_Integer nF)
556 Standard_Integer nEF, nVF, iFlag, i, aNbV;
557 BOPTools_ListIteratorOfListOfPave anIt;
558 TColStd_IndexedMapOfInteger aMVF;
560 BooleanOperations_OnceExplorer aExp(*myDS);
562 aExp.Init(nF, TopAbs_EDGE);
563 for (; aExp.More(); aExp.Next()) {
565 BOPTools_PaveSet& aPaveSet=myPavePool(myDS->RefEdge(nEF));
566 const BOPTools_ListOfPave& aLP=aPaveSet.Set();
567 anIt.Initialize(aLP);
568 for (; anIt.More(); anIt.Next()) {
569 const BOPTools_Pave& aPave=anIt.Value();
576 for (i=1; i<=aNbV; ++i) {
578 const TopoDS_Vertex aVF=TopoDS::Vertex(myDS->Shape(nVF));
579 iFlag=IntTools_Tools::ComputeVV(aNewVertex, aVF);
588 //=======================================================================
589 // function: VertexParameter
591 //=======================================================================
592 void VertexParameter(const IntTools_CommonPrt& aCPart,
595 const IntTools_Range& aR=aCPart.Range1();
596 aT=0.5*(aR.First()+aR.Last());
598 if((aCPart.VertexParameter1() >= aR.First()) &&
599 (aCPart.VertexParameter1() <= aR.Last())) {
600 aT = aCPart.VertexParameter1();
603 //=======================================================================
604 // function: IsOnPave
606 //=======================================================================
607 Standard_Boolean IsOnPave(const Standard_Real& aTR,
608 const IntTools_Range& aCPRange,
609 const Standard_Real& aTolerance)
611 Standard_Boolean bIsOnPave;
612 Standard_Real aT1, aT2, dT1, dT2;
614 aT1=aCPRange.First();
616 bIsOnPave=(aTR>=aT1 && aTR<=aT1);
622 bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);