1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: NMTTools_PaveFiller_5.cxx
24 // Created: Mon Dec 15 11:28:33 2003
25 // Author: Peter KURNEV
28 #include <NMTTools_PaveFiller.hxx>
30 #include <TColStd_IndexedMapOfInteger.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_Builder.hxx>
35 #include <Bnd_Box.hxx>
37 #include <TopAbs_ShapeEnum.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Vertex.hxx>
43 #include <TopoDS_Compound.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
49 #include <IntTools_ShrunkRange.hxx>
50 #include <IntTools_Range.hxx>
51 #include <IntTools_EdgeFace.hxx>
52 #include <IntTools_SequenceOfCommonPrts.hxx>
53 #include <IntTools_CommonPrt.hxx>
54 #include <IntTools_Tools.hxx>
55 #include <IntTools_Context.hxx>
57 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
58 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
59 #include <BooleanOperations_OnceExplorer.hxx>
61 #include <BOPTools_Tools.hxx>
62 #include <BOPTools_Pave.hxx>
63 #include <BOPTools_PaveSet.hxx>
64 #include <BOPTools_ListOfPave.hxx>
65 #include <BOPTools_ListIteratorOfListOfPave.hxx>
66 #include <BOPTools_PaveBlock.hxx>
67 #include <BOPTools_ListOfPaveBlock.hxx>
68 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
69 #include <BOPTools_ESInterference.hxx>
71 #include <BOPTools_CArray1OfVVInterference.hxx>
72 #include <BOPTools_CArray1OfESInterference.hxx>
73 #include <BOPTools_VVInterference.hxx>
74 #include <BOPTools_ESInterference.hxx>
75 #include <BOPTools_IDMapOfPaveBlockIMapOfInteger.hxx>
76 #include <BOPTools_IMapOfPaveBlock.hxx>
77 #include <BRepTools.hxx>
79 #include <NMTDS_ShapesDataStructure.hxx>
80 #include <NMTDS_Iterator.hxx>
81 #include <NMTDS_InterfPool.hxx>
83 #include <NMTTools_ListOfCommonBlock.hxx>
84 #include <NMTTools_CommonBlockAPI.hxx>
85 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
86 #include <NMTTools_CommonBlockAPI.hxx>
87 #include <NMTTools_ListOfCommonBlock.hxx>
88 #include <NMTTools_Tools.hxx>
92 void VertexParameter(const IntTools_CommonPrt& aCPart,
95 Standard_Boolean IsOnPave(const Standard_Real& aTR,
96 const IntTools_Range& aCPRange,
97 const Standard_Real& aTolerance);
99 //=======================================================================
100 // function: PerformEF
102 //=======================================================================
103 void NMTTools_PaveFiller::PerformEF()
105 Standard_Boolean bJustAdd;
106 Standard_Integer n1, n2, anIndexIn, nE, nF, aNbEFs, aBlockLength;
107 Standard_Integer aDiscretize;
108 Standard_Real aTolE, aTolF, aDeflection;
109 BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
110 BOPTools_IDMapOfPaveBlockIMapOfInteger aMapCB;
111 BOPTools_IMapOfPaveBlock aIMPBx;
113 myIsDone=Standard_False;
117 BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
119 myDSIt->Initialize(TopAbs_EDGE, TopAbs_FACE);
121 // BlockLength correction
122 aNbEFs=myDSIt->BlockLength();
123 aBlockLength=aEFs.BlockLength();
124 if (aNbEFs > aBlockLength) {
125 aEFs.SetBlockLength(aNbEFs);
128 for (; myDSIt->More(); myDSIt->Next()) {
129 myDSIt->Current(n1, n2, bJustAdd);
139 if (myDS->GetShapeType(n2)==TopAbs_EDGE) {
144 // all Common Blocks for face nF
145 NMTTools_ListOfCommonBlock aLCBF;
146 CommonBlocksFace(nF, aLCBF);
147 NMTTools_CommonBlockAPI aCBAPIF(aLCBF);
150 const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));
151 if (NMTTools_Tools::IsDegenerated(aE)){
156 const TopoDS_Face aF=TopoDS::Face(myDS->Shape(nF));
158 TopTools_IndexedMapOfShape aME;
159 TopExp::MapShapes(aF, TopAbs_EDGE, aME);
160 if (aME.Contains(aE)) {
164 aTolF=BRep_Tool::Tolerance(aF);
165 aTolE=BRep_Tool::Tolerance(aE);
167 const Bnd_Box& aBBF=myDS->GetBoundingBox(nF);
169 // Process each PaveBlock on edge nE
170 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
172 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
173 for (; anIt.More(); anIt.Next()) {
174 BOPTools_PaveBlock& aPB=anIt.Value();
175 if (aCBAPIF.IsCommonBlock(aPB)) {
179 const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
180 const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
181 const Bnd_Box& aBBE=aShrunkRange.BndBox();
183 if (aBBF.IsOut (aBBE)) {
188 IntTools_EdgeFace aEF;
193 aEF.SetDiscretize (aDiscretize);
194 aEF.SetDeflection (aDeflection);
196 aEF.SetContext(myContext);
198 IntTools_Range anewSR = aSR;
200 // Correction of the Shrunk Range
201 BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
202 aEF.SetRange (anewSR);
204 BRepTools::Write(aE, "/dn20/salome/skv/SALOME/scripts/Dumps/edge");
205 BRepTools::Write(aF, "/dn20/salome/skv/SALOME/scripts/Dumps/face");
209 Standard_Boolean bCoinsideFlag;
210 Standard_Integer i, aNbCPrts;
211 TopAbs_ShapeEnum aType;
213 const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
215 aNbCPrts=aCPrts.Length();
216 for (i=1; i<=aNbCPrts; ++i) {
219 const IntTools_CommonPrt& aCPart=aCPrts(i);
224 case TopAbs_VERTEX: {
225 Standard_Boolean bIsOnPave1, bIsOnPave2;
226 Standard_Integer nVF;
227 Standard_Real aT, aTolToDecide;
228 TopoDS_Vertex aNewVertex;
230 const IntTools_Range& aR=aCPart.Range1();
233 VertexParameter(aCPart, aT);
234 BOPTools_Tools::MakeNewVertex(aE, aT, aF, aNewVertex);
236 //decide to add pave or not
238 bIsOnPave1=IsOnPave(anewSR.First(), aR, aTolToDecide);
239 bIsOnPave2=IsOnPave(anewSR.Last() , aR, aTolToDecide);
241 if (!bIsOnPave1 && !bIsOnPave2) {
242 nVF=CheckFacePaves(aNewVertex, nF);
245 // Add Interference to the Pool
246 BOPTools_ESInterference anInterf (nE, nF, aCPart);
247 anIndexIn=aEFs.Append(anInterf);
248 anInterf.SetNewShape(0);
250 aMapVI.Add(aNewVertex, anIndexIn);
253 myIP->Add(nE, nF, Standard_True, NMTDS_TI_EF);
256 }// if (!bIsOnPave1 && !bIsOnPave2)
258 //modified by NIZNHY-PKV Fri Apr 18 10:55:38 2008f
260 const BOPTools_Pave& aPave=(bIsOnPave1)? aPB.Pave1() : aPB.Pave2();
262 const TopoDS_Vertex& aVF=TopoDS::Vertex(myDS->Shape(nVF));
263 BOPTools_Tools::UpdateVertex (aVF, aNewVertex);
265 //modified by NIZNHY-PKV Fri Apr 18 10:55:40 2008t
267 }// case TopAbs_VERTEX:
271 bCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
272 if (!bCoinsideFlag) {
277 if (aMapCB.Contains(aPB)) {
278 TColStd_IndexedMapOfInteger& aMapF=aMapCB.ChangeFromKey(aPB);
282 TColStd_IndexedMapOfInteger aMapF;
284 aMapCB.Add(aPB, aMapF);
288 myIP->Add(nE, nF, Standard_True, NMTDS_TI_EF);
289 }// case TopAbs_EDGE:
295 } // for (i=1; i<=aNbCPrts; i++)
296 } //if (aEF.IsDone())
297 } // for (; anIt.More(); anIt.Next())
298 }// for (; myDSIt.More(); myDSIt.Next())
300 // Treat New vertices
301 EFNewVertices(aMapVI);
303 // Add draft Common Blocks of EF type
304 EFCommonBlocks(aMapCB);
306 // Collect all CB we suspected to split by new vertices
307 NMTTools_ListOfCommonBlock aLCBx;
309 Standard_Integer i, aNbPBx, nEx;
310 BOPTools_IMapOfPaveBlock aMx;
312 aNbPBx=aIMPBx.Extent();
313 for (i=1; i<=aNbPBx; ++i) {
314 const BOPTools_PaveBlock& aPBx=aIMPBx(i);
315 nEx=aPBx.OriginalEdge();
316 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nEx));
318 NMTTools_CommonBlockAPI aCBAPIx(aLCB);
319 if (aCBAPIx.IsCommonBlock(aPBx)) {
320 NMTTools_CommonBlock& aCBx=aCBAPIx.CommonBlock(aPBx);
321 const BOPTools_PaveBlock& aPB1=aCBx.PaveBlock1();
322 if (!aMx.Contains(aPB1)){
331 // Split the common blocks above
332 if (aLCBx.Extent()) {
333 ReplaceCommonBlocks(aLCBx);
336 myIsDone=Standard_True;
338 //=======================================================================
339 // function:EFCommonBlocks
341 //=======================================================================
342 void NMTTools_PaveFiller::EFCommonBlocks
343 (const BOPTools_IDMapOfPaveBlockIMapOfInteger& aMapCB)
345 Standard_Integer i, aNbPB, nE, j, aNbF, nF;
347 aNbPB=aMapCB.Extent();
348 for (i=1; i<=aNbPB; ++i) {
349 const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
350 const TColStd_IndexedMapOfInteger& aMapF=aMapCB.FindFromIndex(i);
353 nE=aPB.OriginalEdge();
355 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
357 NMTTools_CommonBlockAPI aCBAPI(aLCB);
358 if (aCBAPI.IsCommonBlock(aPB)) {
359 NMTTools_CommonBlock& aCB=aCBAPI.CommonBlock(aPB);
360 for (j=1; j<=aNbF; ++j) {
366 NMTTools_CommonBlock aCB;
368 aCB.AddPaveBlock(aPB);
369 for (j=1; j<=aNbF; ++j) {
377 //=======================================================================
378 // function:EFNewVertices
380 //=======================================================================
381 void NMTTools_PaveFiller::EFNewVertices
382 (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
384 Standard_Integer i, j, aNb, aNewShape, aFlag, iX, aNbVV, aNbSimple;
385 Standard_Integer aWhat, aWith, nE, nF, nV, aNbIEF, aNbEdges, iTmp;
387 TopoDS_Compound aCompound;
388 TopoDS_Vertex aNewVertex;
391 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEF;
392 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
393 TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
396 if (!aNb) { // no new vertices, no new problems
400 BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
404 aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
405 EFNewVertices(aNewVertex, aMapVI);
409 // 1. Make compound from new vertices
410 aBB.MakeCompound(aCompound);
411 for (i=1; i<=aNb; ++i) {
412 const TopoDS_Shape& aV=aMapVI.FindKey(i);
413 aBB.Add(aCompound, aV);
416 // 2. VV intersection between these vertices
417 // using the auxiliary Filler
418 NMTTools_PaveFiller tPF;
420 tPF.SetCompositeShape(aCompound);
425 NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
426 NMTDS_InterfPool& tInterfPool=*(tPF.IP());
427 BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterferences();
429 // 3. Separate Comlex and Simple new vertices
430 aNbVV=aVVInterfs.Extent();
431 for (i=1; i<=aNbVV; ++i) {
432 const BOPTools_VVInterference& aVV=aVVInterfs(i);
433 aVV.Indices(aWhat, aWith);
434 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
435 const TopoDS_Shape& aV2=tDS.Shape(aWith);
436 aMNVComplex.Add(aV1);
437 aMNVComplex.Add(aV2);
440 for (i=1; i<=aNb; ++i) {
441 const TopoDS_Shape& aV=aMapVI.FindKey(i);
442 if (!aMNVComplex.Contains(aV)) {
447 // 4. Treat Simple new Vertices
448 aNbSimple=aMNVSimple.Extent();
449 for (i=1; i<=aNbSimple; ++i) {
450 const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
451 EFNewVertices(aV, aMapVI);
454 // 3. Fill Maps : NewVertex-edges (aMNVE)
455 // NewVertex-interferences (aMNVIEE)
456 aNb=aVVInterfs.Extent();
457 for (i=1; i<=aNb; ++i) {
458 const BOPTools_VVInterference& aVV=aVVInterfs(i);
459 aNewShape=aVV.NewShape();
464 if (!aMNVE.Contains(aNewShape)) {
465 TColStd_IndexedMapOfInteger aMx;
466 aMNVE.Add(aNewShape, aMx);
468 if (!aMNVIEF.Contains(aNewShape)) {
469 TColStd_IndexedMapOfInteger aMx;
470 aMNVIEF.Add(aNewShape, aMx);
473 TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
474 TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.ChangeFromKey(aNewShape);
476 aVV.Indices(aWhat, aWith);
478 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
479 iX=aMapVI.FindFromKey(aV1);
480 const BOPTools_ESInterference& aEF1=aEFs(iX);
481 aEF1.Indices(nE, nF);
483 if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
491 const TopoDS_Shape& aV2=tDS.Shape(aWith);
492 iX=aMapVI.FindFromKey(aV2);
493 const BOPTools_ESInterference& aEF2=aEFs(iX);
494 aEF2.Indices(nE, nF);
496 if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
503 }// for (i=1; i<=aNb; ++i) {
505 // 4. Process new vertices
507 for (i=1; i<=aNb; ++i) { // xx
511 aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
513 // Insert New Vertex in DS;
514 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
515 aNewShape=myDS->NumberOfInsertedShapes();
516 myDS->SetState (aNewShape, BooleanOperations_ON);
518 // Update index of NewShape in EF interferences
519 const TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.FindFromKey(nV);
520 aNbIEF=aMIEF.Extent();
521 for (j=1; j<=aNbIEF; ++j) {
523 BOPTools_ESInterference& aEF=aEFs(iX);
524 aEF.SetNewShape(aNewShape);
527 // Update Paves on all edges
528 const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
529 aNbEdges=aME.Extent();
530 for (j=1; j<=aNbEdges; ++j) {
532 const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));//mpv
534 aFlag=myContext->ComputeVE (aNewVertex, aE, aT);
537 aPave.SetInterference(-1);
538 aPave.SetType (BooleanOperations_EdgeSurface);
539 aPave.SetIndex(aNewShape);
542 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
543 aPaveSet.Append(aPave);
548 //=======================================================================
549 // function:EFNewVertices
551 //=======================================================================
552 void NMTTools_PaveFiller::EFNewVertices
553 (const TopoDS_Vertex& aNewVertex,
554 const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
556 Standard_Integer i, aNewShape, nE, nF;
559 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
561 BOPTools_CArray1OfESInterference& aEFs=myIP->ESInterferences();
563 // Insert New Vertex in DS;
564 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
565 aNewShape=myDS->NumberOfInsertedShapes();
566 myDS->SetState (aNewShape, BooleanOperations_ON);
568 // Insert New Vertex in EFInterference
569 i=aMapVI.FindFromKey(aNewVertex);
570 BOPTools_ESInterference& aEFInterf= aEFs(i);
571 aEFInterf.SetNewShape(aNewShape);
572 // Extract interference info
573 aEFInterf.Indices(nE, nF);
574 if (myDS->GetShapeType(nF)==TopAbs_EDGE) {
577 const IntTools_CommonPrt& aCPart=aEFInterf.CommonPrt();
578 VertexParameter(aCPart, aT);
581 aPave.SetInterference(i);
582 aPave.SetType (BooleanOperations_EdgeSurface);
583 aPave.SetIndex(aNewShape);
585 // Append the Pave to the myPavePoolNew
586 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
587 aPaveSet.Append(aPave);
590 //=======================================================================
591 // function: CheckFacePaves
593 //=======================================================================
594 Standard_Integer NMTTools_PaveFiller::CheckFacePaves
595 (const TopoDS_Vertex& aNewVertex,
596 const Standard_Integer nF)
598 Standard_Integer nEF, nVF, iFlag, i, aNbV, iRet;
599 BOPTools_ListIteratorOfListOfPave anIt;
600 TColStd_IndexedMapOfInteger aMVF;
604 BooleanOperations_OnceExplorer aExp(*myDS);
605 aExp.Init(nF, TopAbs_EDGE);
606 for (; aExp.More(); aExp.Next()) {
608 BOPTools_PaveSet& aPaveSet=myPavePool(myDS->RefEdge(nEF));
609 const BOPTools_ListOfPave& aLP=aPaveSet.Set();
610 anIt.Initialize(aLP);
611 for (; anIt.More(); anIt.Next()) {
612 const BOPTools_Pave& aPave=anIt.Value();
619 for (i=1; i<=aNbV; ++i) {
621 const TopoDS_Vertex aVF=TopoDS::Vertex(myDS->Shape(nVF));
622 iFlag=IntTools_Tools::ComputeVV(aNewVertex, aVF);
630 //=======================================================================
631 // function: VertexParameter
633 //=======================================================================
634 void VertexParameter(const IntTools_CommonPrt& aCPart,
637 const IntTools_Range& aR=aCPart.Range1();
638 aT=0.5*(aR.First()+aR.Last());
639 if((aCPart.VertexParameter1() >= aR.First()) &&
640 (aCPart.VertexParameter1() <= aR.Last())) {
641 aT = aCPart.VertexParameter1();
644 //=======================================================================
645 // function: IsOnPave
647 //=======================================================================
648 Standard_Boolean IsOnPave(const Standard_Real& aTR,
649 const IntTools_Range& aCPRange,
650 const Standard_Real& aTolerance)
652 Standard_Boolean bIsOnPave;
653 Standard_Real aT1, aT2, dT1, dT2;
655 aT1=aCPRange.First();
657 bIsOnPave=(aTR>=aT1 && aTR<=aT1);
664 bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);