1 // Copyright (C) 2007-2008 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
22 // File: NMTTools_PaveFiller_7.cxx
23 // Created: Thu Dec 18 15:14:55 2003
24 // Author: Peter KURNEV
27 #include <NMTTools_PaveFiller.ixx>
29 #include <Bnd_HArray1OfBox.hxx>
30 #include <Bnd_BoundSortBox.hxx>
31 #include <Bnd_Box.hxx>
32 #include <BRepBndLib.hxx>
34 #include <TColStd_MapOfInteger.hxx>
35 #include <TColStd_ListIteratorOfListOfInteger.hxx>
36 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
37 #include <TColStd_ListOfInteger.hxx>
38 #include <TColStd_IndexedMapOfInteger.hxx>
40 #include <TopAbs_Orientation.hxx>
42 #include <TopoDS_Vertex.hxx>
43 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Compound.hxx>
48 #include <TopTools_DataMapIteratorOfDataMapOfIntegerShape.hxx>
49 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
50 #include <TopTools_DataMapOfShapeInteger.hxx>
51 #include <TopTools_DataMapOfShapeShape.hxx>
52 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
53 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger.hxx>
54 #include <TopTools_DataMapOfIntegerShape.hxx>
56 #include <BRep_Builder.hxx>
57 #include <BRep_Tool.hxx>
59 #include <TopExp_Explorer.hxx>
62 #include <IntTools_SequenceOfPntOn2Faces.hxx>
63 #include <IntTools_PntOnFace.hxx>
64 #include <IntTools_PntOn2Faces.hxx>
66 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
68 #include <BOPTools_SSInterference.hxx>
69 #include <BOPTools_CArray1OfSSInterference.hxx>
70 #include <BOPTools_CArray1OfVVInterference.hxx>
71 #include <BOPTools_VVInterference.hxx>
72 #include <BOPTools_Tools.hxx>
73 #include <BOPTools_ListOfPaveBlock.hxx>
74 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
75 #include <BOPTools_PaveBlock.hxx>
76 #include <BOPTools_Pave.hxx>
77 #include <BOPTools_Tools.hxx>
79 #include <NMTDS_Iterator.hxx>
80 #include <NMTDS_ShapesDataStructure.hxx>
81 #include <NMTDS_InterfPool.hxx>
83 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
84 // Modified Thu Sep 14 14:35:18 2006
85 // Contribution of Samtech www.samcef.com BEGIN
87 void FuseVertices(const TopoDS_Shape& aCompound,
88 TopTools_DataMapOfShapeShape& aDMVV);
89 // Contribution of Samtech www.samcef.com END
91 //=======================================================================
92 // function: MakeSplitEdges
94 //=======================================================================
95 void NMTTools_PaveFiller::MakeSplitEdges()
97 myIsDone=Standard_False;
99 Standard_Boolean bIsNewVertex1, bIsNewVertex2;
100 Standard_Integer i, aNbS, nV1, nV2, aNbPaveBlocks, aNewShapeIndex;
101 Standard_Real t1, t2;
102 TopAbs_Orientation anOri;
103 TopoDS_Edge aE, aESplit;
104 TopoDS_Vertex aV1, aV2;
106 aNbS=myDS->NumberOfShapesOfTheObject();
107 for (i=1; i<=aNbS; ++i) {
108 if (myDS->GetShapeType(i) != TopAbs_EDGE)
112 aE=TopoDS::Edge(myDS->Shape(i));
113 if (BRep_Tool::Degenerated(aE)){
117 anOri=aE.Orientation();
118 aE.Orientation(TopAbs_FORWARD);
120 // Making Split Edges
122 // Split Set for the Original Edge i
123 BOPTools_ListOfPaveBlock& aSplitEdges=mySplitShapesPool(myDS->RefEdge(i));
124 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
126 aNbPaveBlocks=aSplitEdges.Extent();
128 for (; aPBIt.More(); aPBIt.Next()) {
129 BOPTools_PaveBlock& aPB=aPBIt.Value();
131 const BOPTools_Pave& aPave1=aPB.Pave1();
134 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
135 aV1.Orientation(TopAbs_FORWARD);
137 const BOPTools_Pave& aPave2=aPB.Pave2();
140 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
141 aV2.Orientation(TopAbs_REVERSED);
143 if (aNbPaveBlocks==1) {
144 bIsNewVertex1=myDS->IsNewShape (nV1);
145 bIsNewVertex2=myDS->IsNewShape (nV2);
146 if (!bIsNewVertex1 && !bIsNewVertex2) {
152 BOPTools_Tools::MakeSplitEdge(aE, aV1, t1, aV2, t2, aESplit);
154 // Add Split Part of the Original Edge to the DS
155 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
157 anASSeq.SetNewSuccessor(nV1);
158 anASSeq.SetNewOrientation(aV1.Orientation());
160 anASSeq.SetNewSuccessor(nV2);
161 anASSeq.SetNewOrientation(aV2.Orientation());
163 if (anOri==TopAbs_INTERNAL) {
164 anASSeq.SetNewAncestor(i);
165 aESplit.Orientation(anOri);
168 myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
169 aNewShapeIndex=myDS->NumberOfInsertedShapes();
170 myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
172 // Fill Split Set for the Original Edge
173 aPB.SetEdge(aNewShapeIndex);
177 myIsDone=Standard_True;
179 //=======================================================================
180 // function: UpdateCommonBlocks
182 //=======================================================================
183 void NMTTools_PaveFiller::UpdateCommonBlocks()
185 myIsDone=Standard_False;
187 Standard_Integer nE, aNbS, nSp, nEx, nSpx;
188 NMTTools_ListIteratorOfListOfCommonBlock aCBIt;
189 BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
191 aNbS=myDS->NumberOfShapesOfTheObject();
193 for (nE=1; nE<=aNbS; ++nE) {
194 if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
197 if (BRep_Tool::Degenerated(TopoDS::Edge(myDS->Shape(nE)))){
201 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
202 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool (myDS->RefEdge(nE));
204 aCBIt.Initialize(aLCB);
205 for (; aCBIt.More(); aCBIt.Next()) {
206 NMTTools_CommonBlock& aCB=aCBIt.Value();
208 //modified by NIZNHY-PKV Wed Nov 8 15:59:46 2006f
209 // Among all PBs of aCB the first PB will be one
210 // that have max tolerance value
212 Standard_Real aTolEx, aTolExMax;
213 BOPTools_ListOfPaveBlock *pLPB, aLPBx;
216 pLPB=(BOPTools_ListOfPaveBlock *)&aCB.PaveBlocks();
217 aPBIt.Initialize(*pLPB);
218 for (; aPBIt.More(); aPBIt.Next()) {
219 const BOPTools_PaveBlock& aPBx=aPBIt.Value();
220 nEx=aPBx.OriginalEdge();
221 const TopoDS_Edge& aEx=TopoDS::Edge(myDS->Shape(nEx));
222 aTolEx=BRep_Tool::Tolerance(aEx);
223 if (aTolEx>aTolExMax) {
235 //modified by NIZNHY-PKV Wed Nov 8 15:59:50 2006t
237 BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
241 const BOPTools_ListOfPaveBlock& aCBLPB=aCB.PaveBlocks();
242 aPBIt.Initialize(aCBLPB);
243 for (; aPBIt.More(); aPBIt.Next()) {
244 BOPTools_PaveBlock& aPBx=aPBIt.Value();
245 nEx=aPBx.OriginalEdge();
250 nSpx=SplitIndex(aPBx);
257 //=======================================================================
258 // function: SplitIndex
260 //=======================================================================
261 Standard_Integer NMTTools_PaveFiller::SplitIndex(const BOPTools_PaveBlock& aPBx)const
263 Standard_Integer anOriginalEdge, anEdgeIndex=0;
265 anOriginalEdge=aPBx.OriginalEdge();
267 const BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(anOriginalEdge));
269 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
270 for (; anIt.More(); anIt.Next()) {
271 BOPTools_PaveBlock& aPB=anIt.Value();
272 if (aPB.IsEqual(aPBx)) {
273 anEdgeIndex=aPB.Edge();
279 //=======================================================================
280 // function: UpdatePaveBlocks
282 //=======================================================================
283 void NMTTools_PaveFiller::UpdatePaveBlocks()
285 myIsDone=Standard_False;
288 Standard_Integer i, aNbFFs, nF1, nF2, aNbF, nF, iRankF, nE, nV1, nV2, aNbPB;
289 Standard_Real aT1, aT2;
290 TColStd_IndexedMapOfInteger aMF, aME;
291 TopExp_Explorer aExp;
292 TopoDS_Vertex aV1, aV2;
294 BOPTools_Pave aPave1, aPave2;
295 BOPTools_PaveBlock aPB;
297 BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
299 aNbFFs=aFFs.Extent();
300 for (i=1; i<=aNbFFs; ++i) {
301 BOPTools_SSInterference& aFFi=aFFs(i);
302 aFFi.Indices(nF1, nF2);
308 for(i=1; i<=aNbF; ++i) {
310 iRankF=myDS->Rank(nF);
311 const TopoDS_Shape aF=myDS->Shape(nF);//mpv
312 aExp.Init(aF, TopAbs_EDGE);
313 for(; aExp.More(); aExp.Next()) {
314 aE=TopoDS::Edge(aExp.Current());
316 if (BRep_Tool::Degenerated(aE)) {
320 nE=myDS->ShapeIndex(aE, iRankF);
322 if (aME.Contains(nE)) {
327 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
332 TopExp::Vertices(aE, aV1, aV2);
334 nV1=myDS->ShapeIndex(aV1, iRankF);
335 aT1=BRep_Tool::Parameter(aV1, aE);
336 aPave1.SetIndex(nV1);
337 aPave1.SetParam(aT1);
339 nV2=myDS->ShapeIndex(aV2, iRankF);
340 aT2=BRep_Tool::Parameter(aV2, aE);
341 aPave2.SetIndex(nV2);
342 aPave2.SetParam(aT2);
345 aPB.SetOriginalEdge(nE);
346 aPB.SetPave1(aPave1);
347 aPB.SetPave2(aPave2);
354 // to treat Alone Vertices between faces
355 // Thu Sep 14 14:35:18 2006
356 // Contribution of Samtech www.samcef.com BEGIN
357 //=======================================================================
358 // function: MakeAloneVertices
360 //=======================================================================
361 void NMTTools_PaveFiller::MakeAloneVertices()
363 Standard_Integer i, aNbFFs, nF1, nF2, j, aNbPnts, nFx, aNbV;
364 Standard_Real aTolF1, aTolF2, aTolSum, aTolV;
365 TColStd_ListIteratorOfListOfInteger aIt;
366 TColStd_ListOfInteger aLI;
368 TopoDS_Compound aCompound;
370 TopTools_DataMapOfShapeListOfInteger aDMVFF, aDMVFF1;
371 TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger aItDMVFF;
372 TopTools_DataMapOfShapeShape aDMVV;
373 TopTools_DataMapOfIntegerShape aDMIV;
374 TopTools_DataMapOfShapeInteger aDMVI;
375 TopTools_DataMapIteratorOfDataMapOfShapeInteger aItDMVI;
376 TopTools_DataMapIteratorOfDataMapOfIntegerShape aItDMIV;
378 aBB.MakeCompound(aCompound);
380 myAloneVertices.Clear();
382 BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
384 // 1. Collect alone vertices from FFs
386 aNbFFs=aFFs.Extent();
387 for (i=1; i<=aNbFFs; ++i) {
388 BOPTools_SSInterference& aFFi=aFFs(i);
389 aFFi.Indices(nF1, nF2);
391 const TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));//mpv
392 const TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));//mpv
394 aTolF1=BRep_Tool::Tolerance(aF1);
395 aTolF2=BRep_Tool::Tolerance(aF2);
396 aTolSum=aTolF1+aTolF2;
402 const IntTools_SequenceOfPntOn2Faces& aSeqAlonePnts=aFFi.AlonePnts();
403 aNbPnts=aSeqAlonePnts.Length();
404 for (j=1; j<=aNbPnts; ++j) {
405 const gp_Pnt& aP=aSeqAlonePnts(j).P1().Pnt();
406 BOPTools_Tools::MakeNewVertex(aP, aTolSum, aV);
407 aDMVFF.Bind(aV, aLI);
408 aBB.Add(aCompound, aV);
416 // 2. Try to fuse alone vertices themselves;
417 FuseVertices(aCompound, aDMVV);
419 // if some are fused, replace them by new ones
420 aItDMVFF.Initialize(aDMVFF);
421 for (; aItDMVFF.More(); aItDMVFF.Next()) {
422 const TopoDS_Shape& aVx=aItDMVFF.Key();
423 const TColStd_ListOfInteger& aLIx=aItDMVFF.Value();
425 if (!aDMVV.IsBound(aVx)) {
426 aDMVFF1.Bind(aVx, aLIx);
429 const TopoDS_Shape& aVy=aDMVV.Find(aVx);
431 if (aDMVFF1.IsBound(aVy)) {
432 TColStd_ListOfInteger& aLIy=aDMVFF1.ChangeFind(aVy);
433 aIt.Initialize(aLIx);
434 for(; aIt.More(); aIt.Next()) {
440 aDMVFF1.Bind(aVy, aLIx);
446 // refine lists of faces in aDMVFF1;
447 aItDMVFF.Initialize(aDMVFF1);
448 for (; aItDMVFF.More(); aItDMVFF.Next()) {
449 TColStd_MapOfInteger aMIy;
450 TColStd_ListOfInteger aLIy;
452 const TopoDS_Shape& aVx=aItDMVFF.Key();
453 TColStd_ListOfInteger& aLIx=aDMVFF1.ChangeFind(aVx);
454 aIt.Initialize(aLIx);
455 for(; aIt.More(); aIt.Next()) {
464 //==================================
466 // 3. Collect vertices from DS
467 Standard_Integer aNbS, nV, nVSD, aNbVDS, i1, i2, aNbVSD;
469 aNbS=myDS->NumberOfShapesOfTheObject();
471 for (i=1; i<=aNbS; ++i) {
472 const TopoDS_Shape& aS=myDS->Shape(i);
473 if (aS.ShapeType() != TopAbs_VERTEX){
477 nVSD=FindSDVertex(i);
478 nV=(nVSD) ? nVSD : i;
479 const TopoDS_Shape& aVx=myDS->Shape(nV);
480 if (!aDMVI.IsBound(aVx)) {
485 i1=myDS->NumberOfSourceShapes()+1;
486 i2=myDS->NumberOfInsertedShapes();
487 for (i=i1; i<=i2; ++i) {
488 const TopoDS_Shape aS=myDS->Shape(i);//mpv
489 if (aS.ShapeType() != TopAbs_VERTEX){
492 if (!aDMVI.IsBound(aS)) {
497 // 4. Initialize BoundSortBox on aDMVI
499 Handle(Bnd_HArray1OfBox) aHAB;
500 Bnd_BoundSortBox aBSB;
502 aNbVDS=aDMVI.Extent();
503 aHAB=new Bnd_HArray1OfBox(1, aNbVDS);
505 aItDMVI.Initialize(aDMVI);
506 for (i=1; aItDMVI.More(); aItDMVI.Next(), ++i) {
510 aV=TopoDS::Vertex(aItDMVI.Key());
511 aTolV=BRep_Tool::Tolerance(aV);
513 BRepBndLib::Add(aV, aBox);
514 aHAB->SetValue(i, aBox);
518 aBSB.Initialize(aHAB);
521 aItDMVFF.Initialize(aDMVFF1);
522 for (; aItDMVFF.More(); aItDMVFF.Next()) {
525 const TColStd_ListOfInteger& aLIFF=aItDMVFF.Value();
526 aV=TopoDS::Vertex(aItDMVFF.Key());
528 aTolV=BRep_Tool::Tolerance(aV);
530 BRepBndLib::Add(aV, aBoxV);
532 const TColStd_ListOfInteger& aLIVSD=aBSB.Compare(aBoxV);
533 aNbVSD=aLIVSD.Extent();
535 // add new vertex in DS and update map myAloneVertices
536 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
538 myDS->InsertShapeAndAncestorsSuccessors(aV, anASSeq);
539 nV=myDS->NumberOfInsertedShapes();
541 aIt.Initialize(aLIFF);
542 for (; aIt.More(); aIt.Next()) {
544 if (myAloneVertices.Contains(nFx)) {
545 TColStd_IndexedMapOfInteger& aMVx=myAloneVertices.ChangeFromKey(nFx);
549 TColStd_IndexedMapOfInteger aMVx;
551 myAloneVertices.Add(nFx, aMVx);
558 Standard_Integer aNbF, aNbAV, nF, k;
559 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMAVF;
561 aNbF=myAloneVertices.Extent();
566 // 1. fill map Alone Vertex/Face -> aMAVF
567 for (i=1; i<=aNbF; ++i) {
568 nF=myAloneVertices.FindKey(i);
569 const TColStd_IndexedMapOfInteger& aMAV=myAloneVertices(i);
571 for(j=1; j<=aNbAV; ++j) {
573 if (aMAVF.Contains(nV)) {
574 TColStd_IndexedMapOfInteger& aMF=aMAVF.ChangeFromKey(nV);
578 TColStd_IndexedMapOfInteger aMF;
585 // 2 Obtain pairs of faces
586 aNbAV=aMAVF.Extent();
587 for (i=1; i<=aNbAV; ++i) {
588 const TColStd_IndexedMapOfInteger& aMF=aMAVF(i);
590 for(j=1; j<aNbF; ++j) {
592 for(k=j+1; k<=aNbF; ++k) {
594 myIP->Add(nF1, nF2, Standard_True, NMTDS_TI_FF);
601 //=======================================================================
602 // function: AloneVertices
604 //=======================================================================
605 const NMTTools_IndexedDataMapOfIndexedMapOfInteger& NMTTools_PaveFiller::AloneVertices()const
607 return myAloneVertices;
609 //=======================================================================
610 // function: FuseVertices
612 //=======================================================================
613 void NMTTools_PaveFiller::FuseVertices(const TopoDS_Shape& aCompound,
614 TopTools_DataMapOfShapeShape& aDMVV)const
616 Standard_Integer i, aNbVV, n1, n2, nX;
617 NMTTools_PaveFiller tPF;
619 tPF.SetCompositeShape(aCompound);
624 //tPF.PerformNewVertices(); //qq
626 NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
627 NMTDS_InterfPool& tInterfPool=*(tPF.IP());
628 BOPTools_CArray1OfVVInterference& aVVt=tInterfPool.VVInterferences();
631 for (i=1; i<=aNbVV; ++i) {
632 const BOPTools_VVInterference& aVV=aVVt(i);
636 const TopoDS_Shape& aV1=tDS.Shape(n1);
637 const TopoDS_Shape& aV2=tDS.Shape(n2);
638 const TopoDS_Shape& aVx=tDS.Shape(nX);
639 aDMVV.Bind(aV1, aVx);
640 aDMVV.Bind(aV2, aVx);
644 // Contribution of Samtech www.samcef.com END