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>
81 #include <TopTools_IndexedMapOfShape.hxx>
85 void VertexParameter(const IntTools_CommonPrt& aCPart,
88 Standard_Boolean IsOnPave(const Standard_Real& aTR,
89 const IntTools_Range& aCPRange,
90 const Standard_Real& aTolerance);
92 //=======================================================================
93 // function: PerformEF
95 //=======================================================================
96 void NMTTools_PaveFiller::PerformEF()
98 myIsDone=Standard_False;
100 Standard_Integer n1, n2, anIndexIn=0, nE, nF, aNbEFs, aBlockLength;
101 Standard_Boolean bJustAdd;
102 Standard_Real aTolE, aTolF, aDeflection=0.01;
103 Standard_Integer aDiscretize=35;
104 BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
105 BOPTools_IDMapOfPaveBlockIMapOfInteger aMapCB;
106 BOPTools_IMapOfPaveBlock aIMPBx;
108 BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
110 myDSIt.Initialize(TopAbs_EDGE, TopAbs_FACE);
112 // BlockLength correction
113 aNbEFs=ExpectedPoolLength();
114 aBlockLength=aEFs.BlockLength();
115 if (aNbEFs > aBlockLength) {
116 aEFs.SetBlockLength(aNbEFs);
119 for (; myDSIt.More(); myDSIt.Next()) {
120 myDSIt.Current(n1, n2, bJustAdd);
123 if (myIntrPool->IsComputed(n1, n2)) {
131 // all Common Blocks for face nF
133 NMTTools_ListOfCommonBlock aLCBF;
134 CommonBlocksFace(nF, aLCBF);
135 NMTTools_CommonBlockAPI aCBAPIF(aLCBF);
138 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
142 const TopoDS_Edge aE=TopoDS::Edge(myDS->GetShape(nE));//mpv
143 if (BRep_Tool::Degenerated(aE)){
147 const TopoDS_Face aF=TopoDS::Face(myDS->GetShape(nF));//mpv
150 // to avoid intersection between face and edge from that face
151 // Thu Sep 14 14:35:18 2006
152 // Contribution of Samtech www.samcef.com BEGIN
153 TopTools_IndexedMapOfShape aME;
155 TopExp::MapShapes(aF, TopAbs_EDGE, aME);
156 if (aME.Contains(aE)) {
159 // Contribution of Samtech www.samcef.com END
161 aTolF=BRep_Tool::Tolerance(aF);
163 // Modified Thu Sep 14 14:35:18 2006
164 // Contribution of Samtech www.samcef.com BEGIN
165 aTolE=BRep_Tool::Tolerance(aE);
166 // Contribution of Samtech www.samcef.com END
168 const Bnd_Box& aBBF=myDS->GetBoundingBox(nF);
170 // Process each PaveBlock on edge nE
171 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
173 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
174 for (; anIt.More(); anIt.Next()) {
175 BOPTools_PaveBlock& aPB=anIt.Value();
177 if (aCBAPIF.IsCommonBlock(aPB)) {
181 const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
182 const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
183 const Bnd_Box& aBBE=aShrunkRange.BndBox();
185 if (aBBF.IsOut (aBBE)) {
190 IntTools_EdgeFace aEF;
195 aEF.SetDiscretize (aDiscretize);
196 aEF.SetDeflection (aDeflection);
198 aEF.SetContext((IntTools_PContext)&myContext);
200 IntTools_Range anewSR = aSR;
202 // Correction of the Shrunk Range
203 BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
204 aEF.SetRange (anewSR);
209 const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
210 Standard_Integer i, aNbCPrts;
211 aNbCPrts=aCPrts.Length();
212 for (i=1; i<=aNbCPrts; i++) {
216 const IntTools_CommonPrt& aCPart=aCPrts(i);
217 TopAbs_ShapeEnum aType=aCPart.Type();
220 case TopAbs_VERTEX: {
221 Standard_Boolean bIsOnPave1, bIsOnPave2;
222 Standard_Integer nVF;
223 Standard_Real aT, aTolToDecide;
224 TopoDS_Vertex aNewVertex;
226 const IntTools_Range& aR=aCPart.Range1();
229 VertexParameter(aCPart, aT);
230 BOPTools_Tools::MakeNewVertex(aE, aT, aF, aNewVertex);
232 //decide to add pave or not
235 bIsOnPave1=IsOnPave(anewSR.First(), aR, aTolToDecide);
236 bIsOnPave2=IsOnPave(anewSR.Last() , aR, aTolToDecide);
238 if (!bIsOnPave1 && !bIsOnPave2) {
239 nVF=CheckFacePaves(aNewVertex, nF);
242 // Add Interference to the Pool
243 BOPTools_ESInterference anInterf (nE, nF, aCPart);
244 anIndexIn=aEFs.Append(anInterf);
245 anInterf.SetNewShape(0);
247 aMapVI.Add(aNewVertex, anIndexIn);
251 }// if (!bIsOnPave1 && !bIsOnPave2)
252 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
253 }// case TopAbs_VERTEX:
257 Standard_Boolean aCoinsideFlag;
259 aCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
260 if (!aCoinsideFlag) {
261 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
266 if (aMapCB.Contains(aPB)) {
267 TColStd_IndexedMapOfInteger& aMapF=aMapCB.ChangeFromKey(aPB);
271 TColStd_IndexedMapOfInteger aMapF;
273 aMapCB.Add(aPB, aMapF);
275 //modified by NIZNHY-PKV Fri Jan 23 14:13:08 2004 f
277 //modified by NIZNHY-PKV Fri Jan 23 14:13:10 2004 t
278 }// case TopAbs_EDGE:
284 } // for (i=1; i<=aNbCPrts; i++)
285 } //if (aEF.IsDone())
286 } // for (; anIt.More(); anIt.Next())
287 }// for (; myDSIt.More(); myDSIt.Next())
289 // Treat New vertices
290 EFNewVertices(aMapVI);
292 // Add draft Common Blocks of EF type
293 EFCommonBlocks(aMapCB);
295 // Collect all CB we suspected to split by new vertices
296 NMTTools_ListOfCommonBlock aLCBx;
298 Standard_Integer i, aNbPBx, nEx;
299 BOPTools_IMapOfPaveBlock aMx;
301 aNbPBx=aIMPBx.Extent();
302 for (i=1; i<=aNbPBx; ++i) {
303 const BOPTools_PaveBlock& aPBx=aIMPBx(i);
304 nEx=aPBx.OriginalEdge();
305 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nEx));
307 NMTTools_CommonBlockAPI aCBAPIx(aLCB);
308 if (aCBAPIx.IsCommonBlock(aPBx)) {
309 NMTTools_CommonBlock& aCBx=aCBAPIx.CommonBlock(aPBx);
310 const BOPTools_PaveBlock& aPB1=aCBx.PaveBlock1();
311 if (!aMx.Contains(aPB1)){
320 // Split the common blocks above
321 if (aLCBx.Extent()) {
322 ReplaceCommonBlocks(aLCBx);
325 myIsDone=Standard_True;
327 //=======================================================================
328 // function:EFCommonBlocks
330 //=======================================================================
331 void NMTTools_PaveFiller::EFCommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfInteger& aMapCB)
333 Standard_Integer i, aNbPB, nE, j, aNbF, nF;
335 aNbPB=aMapCB.Extent();
337 for (i=1; i<=aNbPB; ++i) {
338 const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
339 const TColStd_IndexedMapOfInteger& aMapF=aMapCB.FindFromIndex(i);
342 nE=aPB.OriginalEdge();
344 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
346 NMTTools_CommonBlockAPI aCBAPI(aLCB);
347 if (aCBAPI.IsCommonBlock(aPB)) {
348 NMTTools_CommonBlock& aCB=aCBAPI.CommonBlock(aPB);
349 for (j=1; j<=aNbF; ++j) {
355 NMTTools_CommonBlock aCB;
357 aCB.AddPaveBlock(aPB);
358 for (j=1; j<=aNbF; ++j) {
366 //=======================================================================
367 // function:EFNewVertices
369 //=======================================================================
370 void NMTTools_PaveFiller::EFNewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
372 Standard_Integer i, j, aNb, aNewShape, aFlag, iX, aNbVV, aNbSimple;
373 Standard_Integer aWhat, aWith, nE, nF, nV, aNbIEF, aNbEdges;
375 TopoDS_Compound aCompound;
376 TopoDS_Vertex aNewVertex;
379 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEF;
380 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
381 TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
383 BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
387 if (!aNb) { // no new vertices, no new problems
393 aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
394 EFNewVertices(aNewVertex, aMapVI);
398 // 1. Make compound from new vertices
399 aBB.MakeCompound(aCompound);
400 for (i=1; i<=aNb; ++i) {
401 const TopoDS_Shape& aV=aMapVI.FindKey(i);
402 aBB.Add(aCompound, aV);
405 // 2. VV intersection between these vertices
406 // using the auxiliary Filler
407 NMTDS_ShapesDataStructure tDS;
409 tDS.SetCompositeShape(aCompound);
412 BOPTools_InterferencePool tInterfPool(tDS);
413 NMTTools_PaveFiller tPaveFiller(tInterfPool);
417 tPaveFiller.PerformVV();
418 tPaveFiller.PerformNewVertices();
420 const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
422 // 3. Separate Comlex and Simple new vertices
423 aNbVV=aVVInterfs.Extent();
424 for (i=1; i<=aNbVV; ++i) {
425 const BOPTools_VVInterference& aVV=aVVInterfs(i);
426 aVV.Indices(aWhat, aWith);
427 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
428 const TopoDS_Shape& aV2=tDS.Shape(aWith);
429 aMNVComplex.Add(aV1);
430 aMNVComplex.Add(aV2);
433 for (i=1; i<=aNb; ++i) {
434 const TopoDS_Shape& aV=aMapVI.FindKey(i);
435 if (!aMNVComplex.Contains(aV)) {
440 // 4. Treat Simple new Vertices
441 aNbSimple=aMNVSimple.Extent();
442 for (i=1; i<=aNbSimple; ++i) {
443 const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
444 EFNewVertices(aV, aMapVI);
447 // 3. Fill Maps : NewVertex-edges (aMNVE)
448 // NewVertex-interferences (aMNVIEE)
449 aNb=aVVInterfs.Extent();
450 for (i=1; i<=aNb; ++i) {
451 const BOPTools_VVInterference& aVV=aVVInterfs(i);
452 aNewShape=aVV.NewShape();
457 if (!aMNVE.Contains(aNewShape)) {
458 TColStd_IndexedMapOfInteger aMx;
459 aMNVE.Add(aNewShape, aMx);
461 if (!aMNVIEF.Contains(aNewShape)) {
462 TColStd_IndexedMapOfInteger aMx;
463 aMNVIEF.Add(aNewShape, aMx);
466 TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
467 TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.ChangeFromKey(aNewShape);
469 aVV.Indices(aWhat, aWith);
471 const TopoDS_Shape& aV1=tDS.Shape(aWhat);
472 iX=aMapVI.FindFromKey(aV1);
473 const BOPTools_ESInterference& aEF1=aEFs(iX);
474 aEF1.Indices(nE, nF);
479 const TopoDS_Shape& aV2=tDS.Shape(aWith);
480 iX=aMapVI.FindFromKey(aV2);
481 const BOPTools_ESInterference& aEF2=aEFs(iX);
482 aEF2.Indices(nE, nF);
487 // 4. Process new vertices
489 for (i=1; i<=aNb; ++i) { // xx
493 aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
495 // Insert New Vertex in DS;
496 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
497 aNewShape=myDS->NumberOfInsertedShapes();
498 myDS->SetState (aNewShape, BooleanOperations_ON);
500 // Update index of NewShape in EF interferences
501 const TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.FindFromKey(nV);
502 aNbIEF=aMIEF.Extent();
503 for (j=1; j<=aNbIEF; ++j) {
505 BOPTools_ESInterference& aEF=aEFs(iX);
506 aEF.SetNewShape(aNewShape);
509 // Update Paves on all edges
510 const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
511 aNbEdges=aME.Extent();
512 for (j=1; j<=aNbEdges; ++j) {
514 const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));//mpv
516 aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
519 aPave.SetInterference(-1);
520 aPave.SetType (BooleanOperations_EdgeSurface);
521 aPave.SetIndex(aNewShape);
524 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
525 aPaveSet.Append(aPave);
530 //=======================================================================
531 // function:EFNewVertices
533 //=======================================================================
534 void NMTTools_PaveFiller::EFNewVertices (const TopoDS_Vertex& aNewVertex,
535 const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI)
537 Standard_Integer i, aNewShape, nE, nF;
540 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
542 BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
544 // Insert New Vertex in DS;
545 myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
546 aNewShape=myDS->NumberOfInsertedShapes();
547 myDS->SetState (aNewShape, BooleanOperations_ON);
548 // Insert New Vertex in EFInterference
549 i=aMapVI.FindFromKey(aNewVertex);
550 BOPTools_ESInterference& aEFInterf= aEFs(i);
551 aEFInterf.SetNewShape(aNewShape);
552 // Extract interference info
553 aEFInterf.Indices(nE, nF);
555 const IntTools_CommonPrt& aCPart=aEFInterf.CommonPrt();
556 VertexParameter(aCPart, aT);
559 aPave.SetInterference(i);
560 aPave.SetType (BooleanOperations_EdgeSurface);
561 aPave.SetIndex(aNewShape);
563 // Append the Pave to the myPavePoolNew
564 BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
565 aPaveSet.Append(aPave);
568 //=======================================================================
569 // function: CheckFacePaves
571 //=======================================================================
572 Standard_Integer NMTTools_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aNewVertex,
573 const Standard_Integer nF)
575 Standard_Integer nEF, nVF, iFlag, i, aNbV;
576 BOPTools_ListIteratorOfListOfPave anIt;
577 TColStd_IndexedMapOfInteger aMVF;
579 BooleanOperations_OnceExplorer aExp(*myDS);
581 aExp.Init(nF, TopAbs_EDGE);
582 for (; aExp.More(); aExp.Next()) {
584 BOPTools_PaveSet& aPaveSet=myPavePool(myDS->RefEdge(nEF));
585 const BOPTools_ListOfPave& aLP=aPaveSet.Set();
586 anIt.Initialize(aLP);
587 for (; anIt.More(); anIt.Next()) {
588 const BOPTools_Pave& aPave=anIt.Value();
595 for (i=1; i<=aNbV; ++i) {
597 const TopoDS_Vertex aVF=TopoDS::Vertex(myDS->Shape(nVF));//mpv
598 iFlag=IntTools_Tools::ComputeVV(aNewVertex, aVF);
607 //=======================================================================
608 // function: VertexParameter
610 //=======================================================================
611 void VertexParameter(const IntTools_CommonPrt& aCPart,
614 const IntTools_Range& aR=aCPart.Range1();
615 aT=0.5*(aR.First()+aR.Last());
617 if((aCPart.VertexParameter1() >= aR.First()) &&
618 (aCPart.VertexParameter1() <= aR.Last())) {
619 aT = aCPart.VertexParameter1();
622 //=======================================================================
623 // function: IsOnPave
625 //=======================================================================
626 Standard_Boolean IsOnPave(const Standard_Real& aTR,
627 const IntTools_Range& aCPRange,
628 const Standard_Real& aTolerance)
630 Standard_Boolean bIsOnPave;
631 Standard_Real aT1, aT2, dT1, dT2;
633 aT1=aCPRange.First();
635 bIsOnPave=(aTR>=aT1 && aTR<=aT1);
641 bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);