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>
45 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <IntTools_ShrunkRange.hxx>
48 #include <IntTools_Range.hxx>
49 #include <IntTools_EdgeFace.hxx>
50 #include <IntTools_PContext.hxx>
51 #include <IntTools_SequenceOfCommonPrts.hxx>
52 #include <IntTools_CommonPrt.hxx>
53 #include <IntTools_Tools.hxx>
55 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
56 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
57 #include <BooleanOperations_OnceExplorer.hxx>
59 #include <BOPTools_Tools.hxx>
60 #include <BOPTools_Pave.hxx>
61 #include <BOPTools_PaveSet.hxx>
62 #include <BOPTools_ListOfPave.hxx>
63 #include <BOPTools_ListIteratorOfListOfPave.hxx>
64 #include <BOPTools_PaveBlock.hxx>
65 #include <BOPTools_ListOfPaveBlock.hxx>
66 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
67 #include <BOPTools_ESInterference.hxx>
69 #include <BOPTools_CArray1OfVVInterference.hxx>
70 #include <BOPTools_CArray1OfESInterference.hxx>
71 #include <BOPTools_VVInterference.hxx>
72 #include <BOPTools_ESInterference.hxx>
73 #include <BOPTools_IDMapOfPaveBlockIMapOfInteger.hxx>
74 #include <BOPTools_IMapOfPaveBlock.hxx>
76 #include <NMTDS_ShapesDataStructure.hxx>
77 #include <NMTDS_Iterator.hxx>
78 #include <NMTDS_InterfPool.hxx>
80 #include <NMTTools_ListOfCommonBlock.hxx>
81 #include <NMTTools_CommonBlockAPI.hxx>
82 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
83 #include <NMTTools_CommonBlockAPI.hxx>
84 #include <NMTTools_ListOfCommonBlock.hxx>
88 void VertexParameter(const IntTools_CommonPrt& aCPart,
91 Standard_Boolean IsOnPave(const Standard_Real& aTR,
92 const IntTools_Range& aCPRange,
93 const Standard_Real& aTolerance);
95 //=======================================================================
96 // function: PerformEF
98 //=======================================================================
99 void NMTTools_PaveFiller::PerformEF()
101 myIsDone=Standard_False;
103 Standard_Integer n1, n2, anIndexIn=0, nE, nF, aNbEFs, aBlockLength;
104 Standard_Boolean bJustAdd;
105 Standard_Real aTolE, aTolF, aDeflection=0.01;
106 Standard_Integer aDiscretize=35;
107 BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
108 BOPTools_IDMapOfPaveBlockIMapOfInteger aMapCB;
109 BOPTools_IMapOfPaveBlock aIMPBx;
111 BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
113 myDSIt->Initialize(TopAbs_EDGE, TopAbs_FACE);
115 // BlockLength correction
116 aNbEFs=myDSIt->BlockLength();
117 aBlockLength=aEFs.BlockLength();
118 if (aNbEFs > aBlockLength) {
119 aEFs.SetBlockLength(aNbEFs);
122 for (; myDSIt->More(); myDSIt->Next()) {
123 myDSIt->Current(n1, n2, bJustAdd);
126 //if (myIntrPool->IsComputed(n1, n2)) {
132 if (myDS->GetShapeType(n2)==TopAbs_EDGE) {
138 // all Common Blocks for face nF
140 NMTTools_ListOfCommonBlock aLCBF;
141 CommonBlocksFace(nF, aLCBF);
142 NMTTools_CommonBlockAPI aCBAPIF(aLCBF);
145 //myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
149 const TopoDS_Edge aE=TopoDS::Edge(myDS->GetShape(nE));//mpv
150 if (BRep_Tool::Degenerated(aE)){
154 const TopoDS_Face aF=TopoDS::Face(myDS->GetShape(nF));//mpv
157 // to avoid intersection between face and edge from that face
158 // Thu Sep 14 14:35:18 2006
159 // Contribution of Samtech www.samcef.com BEGIN
160 TopTools_IndexedMapOfShape aME;
162 TopExp::MapShapes(aF, TopAbs_EDGE, aME);
163 if (aME.Contains(aE)) {
166 // Contribution of Samtech www.samcef.com END
168 aTolF=BRep_Tool::Tolerance(aF);
170 // Modified Thu Sep 14 14:35:18 2006
171 // Contribution of Samtech www.samcef.com BEGIN
172 aTolE=BRep_Tool::Tolerance(aE);
173 // Contribution of Samtech www.samcef.com END
175 const Bnd_Box& aBBF=myDS->GetBoundingBox(nF);
177 // Process each PaveBlock on edge nE
178 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
180 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
181 for (; anIt.More(); anIt.Next()) {
182 BOPTools_PaveBlock& aPB=anIt.Value();
184 if (aCBAPIF.IsCommonBlock(aPB)) {
188 const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
189 const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
190 const Bnd_Box& aBBE=aShrunkRange.BndBox();
192 if (aBBF.IsOut (aBBE)) {
197 IntTools_EdgeFace aEF;
202 aEF.SetDiscretize (aDiscretize);
203 aEF.SetDeflection (aDeflection);
205 aEF.SetContext((IntTools_PContext)&myContext);
207 IntTools_Range anewSR = aSR;
209 // Correction of the Shrunk Range
210 BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
211 aEF.SetRange (anewSR);
216 const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
217 Standard_Integer i, aNbCPrts;
218 aNbCPrts=aCPrts.Length();
219 for (i=1; i<=aNbCPrts; i++) {
223 const IntTools_CommonPrt& aCPart=aCPrts(i);
224 TopAbs_ShapeEnum aType=aCPart.Type();
227 case TopAbs_VERTEX: {
228 Standard_Boolean bIsOnPave1, bIsOnPave2;
229 Standard_Integer nVF;
230 Standard_Real aT, aTolToDecide;
231 TopoDS_Vertex aNewVertex;
233 const IntTools_Range& aR=aCPart.Range1();
236 VertexParameter(aCPart, aT);
237 BOPTools_Tools::MakeNewVertex(aE, aT, aF, aNewVertex);
239 //decide to add pave or not
242 bIsOnPave1=IsOnPave(anewSR.First(), aR, aTolToDecide);
243 bIsOnPave2=IsOnPave(anewSR.Last() , aR, aTolToDecide);
245 if (!bIsOnPave1 && !bIsOnPave2) {
246 nVF=CheckFacePaves(aNewVertex, nF);
249 // Add Interference to the Pool
250 BOPTools_ESInterference anInterf (nE, nF, aCPart);
251 anIndexIn=aEFs.Append(anInterf);
252 anInterf.SetNewShape(0);
254 aMapVI.Add(aNewVertex, anIndexIn);
258 myIP->Add(nE, nF, Standard_True, NMTDS_TI_EF);
263 }// if (!bIsOnPave1 && !bIsOnPave2)
264 //myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
265 }// case TopAbs_VERTEX:
269 Standard_Boolean aCoinsideFlag;
271 aCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
272 if (!aCoinsideFlag) {
273 //myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
278 if (aMapCB.Contains(aPB)) {
279 TColStd_IndexedMapOfInteger& aMapF=aMapCB.ChangeFromKey(aPB);
283 TColStd_IndexedMapOfInteger aMapF;
285 aMapCB.Add(aPB, aMapF);
290 myIP->Add(nE, nF, Standard_True, NMTDS_TI_EF);
293 }// case TopAbs_EDGE:
299 } // for (i=1; i<=aNbCPrts; i++)
300 } //if (aEF.IsDone())
301 } // for (; anIt.More(); anIt.Next())
302 }// for (; myDSIt.More(); myDSIt.Next())
304 // Treat New vertices
305 EFNewVertices(aMapVI);
307 // Add draft Common Blocks of EF type
308 EFCommonBlocks(aMapCB);
310 // Collect all CB we suspected to split by new vertices
311 NMTTools_ListOfCommonBlock aLCBx;
313 Standard_Integer i, aNbPBx, nEx;
314 BOPTools_IMapOfPaveBlock aMx;
316 aNbPBx=aIMPBx.Extent();
317 for (i=1; i<=aNbPBx; ++i) {
318 const BOPTools_PaveBlock& aPBx=aIMPBx(i);
319 nEx=aPBx.OriginalEdge();
320 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nEx));
322 NMTTools_CommonBlockAPI aCBAPIx(aLCB);
323 if (aCBAPIx.IsCommonBlock(aPBx)) {
324 NMTTools_CommonBlock& aCBx=aCBAPIx.CommonBlock(aPBx);
325 const BOPTools_PaveBlock& aPB1=aCBx.PaveBlock1();
326 if (!aMx.Contains(aPB1)){
335 // Split the common blocks above
336 if (aLCBx.Extent()) {
337 ReplaceCommonBlocks(aLCBx);
340 myIsDone=Standard_True;
342 //=======================================================================
343 // function:EFCommonBlocks
345 //=======================================================================
346 void NMTTools_PaveFiller::EFCommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfInteger& aMapCB)
348 Standard_Integer i, aNbPB, nE, j, aNbF, nF;
350 aNbPB=aMapCB.Extent();
352 for (i=1; i<=aNbPB; ++i) {
353 const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
354 const TColStd_IndexedMapOfInteger& aMapF=aMapCB.FindFromIndex(i);
357 nE=aPB.OriginalEdge();
359 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
361 NMTTools_CommonBlockAPI aCBAPI(aLCB);
362 if (aCBAPI.IsCommonBlock(aPB)) {
363 NMTTools_CommonBlock& aCB=aCBAPI.CommonBlock(aPB);
364 for (j=1; j<=aNbF; ++j) {
370 NMTTools_CommonBlock aCB;
372 aCB.AddPaveBlock(aPB);
373 for (j=1; j<=aNbF; ++j) {
381 //=======================================================================
382 // function:EFNewVertices
384 //=======================================================================
385 void NMTTools_PaveFiller::EFNewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
387 Standard_Integer i, j, aNb, aNewShape, aFlag, iX, aNbVV, aNbSimple;
388 Standard_Integer aWhat, aWith, nE, nF, nV, aNbIEF, aNbEdges, iTmp;
390 TopoDS_Compound aCompound;
391 TopoDS_Vertex aNewVertex;
394 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEF;
395 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
396 TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
398 BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
402 if (!aNb) { // no new vertices, no new problems
408 aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
409 EFNewVertices(aNewVertex, aMapVI);
413 // 1. Make compound from new vertices
414 aBB.MakeCompound(aCompound);
415 for (i=1; i<=aNb; ++i) {
416 const TopoDS_Shape& aV=aMapVI.FindKey(i);
417 aBB.Add(aCompound, aV);
420 // 2. VV intersection between these vertices
421 // using the auxiliary Filler
422 NMTTools_PaveFiller tPF;
424 tPF.SetCompositeShape(aCompound);
428 //tPF.PerformNewVertices(); qq
430 NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
431 //const BOPTools_InterferencePool& tInterfPool=*(tPF.InterfPool());
432 NMTDS_InterfPool& tInterfPool=*(tPF.IP());
433 //const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
434 BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterferences();
436 // 3. Separate Comlex and Simple new vertices
437 aNbVV=aVVInterfs.Extent();
438 for (i=1; i<=aNbVV; ++i) {
439 const BOPTools_VVInterference& aVV=aVVInterfs(i);
440 aVV.Indices(aWhat, aWith);
441 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
442 const TopoDS_Shape& aV2=tDS.Shape(aWith);
443 aMNVComplex.Add(aV1);
444 aMNVComplex.Add(aV2);
447 for (i=1; i<=aNb; ++i) {
448 const TopoDS_Shape& aV=aMapVI.FindKey(i);
449 if (!aMNVComplex.Contains(aV)) {
454 // 4. Treat Simple new Vertices
455 aNbSimple=aMNVSimple.Extent();
456 for (i=1; i<=aNbSimple; ++i) {
457 const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
458 EFNewVertices(aV, aMapVI);
461 // 3. Fill Maps : NewVertex-edges (aMNVE)
462 // NewVertex-interferences (aMNVIEE)
463 aNb=aVVInterfs.Extent();
464 for (i=1; i<=aNb; ++i) {
465 const BOPTools_VVInterference& aVV=aVVInterfs(i);
466 aNewShape=aVV.NewShape();
471 if (!aMNVE.Contains(aNewShape)) {
472 TColStd_IndexedMapOfInteger aMx;
473 aMNVE.Add(aNewShape, aMx);
475 if (!aMNVIEF.Contains(aNewShape)) {
476 TColStd_IndexedMapOfInteger aMx;
477 aMNVIEF.Add(aNewShape, aMx);
480 TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
481 TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.ChangeFromKey(aNewShape);
483 aVV.Indices(aWhat, aWith);
485 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
486 iX=aMapVI.FindFromKey(aV1);
487 const BOPTools_ESInterference& aEF1=aEFs(iX);
488 aEF1.Indices(nE, nF);
490 if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
498 const TopoDS_Shape& aV2=tDS.Shape(aWith);
499 iX=aMapVI.FindFromKey(aV2);
500 const BOPTools_ESInterference& aEF2=aEFs(iX);
501 aEF2.Indices(nE, nF);
503 if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
511 // 4. Process new vertices
513 for (i=1; i<=aNb; ++i) { // xx
517 aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
519 // Insert New Vertex in DS;
520 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
521 aNewShape=myDS->NumberOfInsertedShapes();
522 myDS->SetState (aNewShape, BooleanOperations_ON);
524 // Update index of NewShape in EF interferences
525 const TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.FindFromKey(nV);
526 aNbIEF=aMIEF.Extent();
527 for (j=1; j<=aNbIEF; ++j) {
529 BOPTools_ESInterference& aEF=aEFs(iX);
530 aEF.SetNewShape(aNewShape);
533 // Update Paves on all edges
534 const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
535 aNbEdges=aME.Extent();
536 for (j=1; j<=aNbEdges; ++j) {
538 const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));//mpv
540 aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
543 aPave.SetInterference(-1);
544 aPave.SetType (BooleanOperations_EdgeSurface);
545 aPave.SetIndex(aNewShape);
548 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
549 aPaveSet.Append(aPave);
554 //=======================================================================
555 // function:EFNewVertices
557 //=======================================================================
558 void NMTTools_PaveFiller::EFNewVertices (const TopoDS_Vertex& aNewVertex,
559 const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
561 Standard_Integer i, aNewShape, nE, nF;
564 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
566 BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
568 // Insert New Vertex in DS;
569 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
570 aNewShape=myDS->NumberOfInsertedShapes();
571 myDS->SetState (aNewShape, BooleanOperations_ON);
572 // Insert New Vertex in EFInterference
573 i=aMapVI.FindFromKey(aNewVertex);
574 BOPTools_ESInterference& aEFInterf= aEFs(i);
575 aEFInterf.SetNewShape(aNewShape);
576 // Extract interference info
577 aEFInterf.Indices(nE, nF);
579 if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
582 const IntTools_CommonPrt& aCPart=aEFInterf.CommonPrt();
583 VertexParameter(aCPart, aT);
586 aPave.SetInterference(i);
587 aPave.SetType (BooleanOperations_EdgeSurface);
588 aPave.SetIndex(aNewShape);
590 // Append the Pave to the myPavePoolNew
591 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
592 aPaveSet.Append(aPave);
595 //=======================================================================
596 // function: CheckFacePaves
598 //=======================================================================
599 Standard_Integer NMTTools_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aNewVertex,
600 const Standard_Integer nF)
602 Standard_Integer nEF, nVF, iFlag, i, aNbV;
603 BOPTools_ListIteratorOfListOfPave anIt;
604 TColStd_IndexedMapOfInteger aMVF;
606 BooleanOperations_OnceExplorer aExp(*myDS);
608 aExp.Init(nF, TopAbs_EDGE);
609 for (; aExp.More(); aExp.Next()) {
611 BOPTools_PaveSet& aPaveSet=myPavePool(myDS->RefEdge(nEF));
612 const BOPTools_ListOfPave& aLP=aPaveSet.Set();
613 anIt.Initialize(aLP);
614 for (; anIt.More(); anIt.Next()) {
615 const BOPTools_Pave& aPave=anIt.Value();
622 for (i=1; i<=aNbV; ++i) {
624 const TopoDS_Vertex aVF=TopoDS::Vertex(myDS->Shape(nVF));//mpv
625 iFlag=IntTools_Tools::ComputeVV(aNewVertex, aVF);
634 //=======================================================================
635 // function: VertexParameter
637 //=======================================================================
638 void VertexParameter(const IntTools_CommonPrt& aCPart,
641 const IntTools_Range& aR=aCPart.Range1();
642 aT=0.5*(aR.First()+aR.Last());
644 if((aCPart.VertexParameter1() >= aR.First()) &&
645 (aCPart.VertexParameter1() <= aR.Last())) {
646 aT = aCPart.VertexParameter1();
649 //=======================================================================
650 // function: IsOnPave
652 //=======================================================================
653 Standard_Boolean IsOnPave(const Standard_Real& aTR,
654 const IntTools_Range& aCPRange,
655 const Standard_Real& aTolerance)
657 Standard_Boolean bIsOnPave;
658 Standard_Real aT1, aT2, dT1, dT2;
660 aT1=aCPRange.First();
662 bIsOnPave=(aTR>=aT1 && aTR<=aT1);
668 bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);