1 // Copyright (C) 2007-2010 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_7.cxx
24 // Created: Thu Dec 18 15:14:55 2003
25 // Author: Peter KURNEV
28 #include <NMTTools_PaveFiller.ixx>
30 #include <Bnd_HArray1OfBox.hxx>
31 #include <Bnd_BoundSortBox.hxx>
32 #include <Bnd_Box.hxx>
33 #include <BRepBndLib.hxx>
35 #include <TColStd_MapOfInteger.hxx>
36 #include <TColStd_ListIteratorOfListOfInteger.hxx>
37 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
38 #include <TColStd_ListOfInteger.hxx>
39 #include <TColStd_IndexedMapOfInteger.hxx>
41 #include <TopAbs_Orientation.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopoDS_Compound.hxx>
49 #include <TopTools_DataMapIteratorOfDataMapOfIntegerShape.hxx>
50 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
51 #include <TopTools_DataMapOfShapeInteger.hxx>
52 #include <TopTools_DataMapOfShapeShape.hxx>
53 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger.hxx>
55 #include <TopTools_DataMapOfIntegerShape.hxx>
57 #include <BRep_Builder.hxx>
58 #include <BRep_Tool.hxx>
60 #include <TopExp_Explorer.hxx>
63 #include <IntTools_SequenceOfPntOn2Faces.hxx>
64 #include <IntTools_PntOnFace.hxx>
65 #include <IntTools_PntOn2Faces.hxx>
67 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
69 #include <BOPTools_SSInterference.hxx>
70 #include <BOPTools_CArray1OfSSInterference.hxx>
71 #include <BOPTools_CArray1OfVVInterference.hxx>
72 #include <BOPTools_VVInterference.hxx>
73 #include <BOPTools_Tools.hxx>
74 #include <BOPTools_ListOfPaveBlock.hxx>
75 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
76 #include <BOPTools_PaveBlock.hxx>
77 #include <BOPTools_Pave.hxx>
78 #include <BOPTools_Tools.hxx>
80 #include <NMTDS_Iterator.hxx>
81 #include <NMTDS_ShapesDataStructure.hxx>
82 #include <NMTDS_InterfPool.hxx>
84 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
85 // Modified Thu Sep 14 14:35:18 2006
86 // Contribution of Samtech www.samcef.com BEGIN
88 void FuseVertices(const TopoDS_Shape& aCompound,
89 TopTools_DataMapOfShapeShape& aDMVV);
90 // Contribution of Samtech www.samcef.com END
92 //=======================================================================
93 // function: MakeSplitEdges
95 //=======================================================================
96 void NMTTools_PaveFiller::MakeSplitEdges()
98 myIsDone=Standard_False;
100 Standard_Boolean bIsNewVertex1, bIsNewVertex2;
101 Standard_Integer i, aNbS, nV1, nV2, aNbPaveBlocks, aNewShapeIndex;
102 Standard_Real t1, t2;
103 TopAbs_Orientation anOri;
104 TopoDS_Edge aE, aESplit;
105 TopoDS_Vertex aV1, aV2;
107 aNbS=myDS->NumberOfShapesOfTheObject();
108 for (i=1; i<=aNbS; ++i) {
109 if (myDS->GetShapeType(i) != TopAbs_EDGE)
113 aE=TopoDS::Edge(myDS->Shape(i));
114 if (BRep_Tool::Degenerated(aE)){
118 anOri=aE.Orientation();
119 aE.Orientation(TopAbs_FORWARD);
121 // Making Split Edges
123 // Split Set for the Original Edge i
124 BOPTools_ListOfPaveBlock& aSplitEdges=mySplitShapesPool(myDS->RefEdge(i));
125 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
127 aNbPaveBlocks=aSplitEdges.Extent();
129 for (; aPBIt.More(); aPBIt.Next()) {
130 BOPTools_PaveBlock& aPB=aPBIt.Value();
132 const BOPTools_Pave& aPave1=aPB.Pave1();
135 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
136 aV1.Orientation(TopAbs_FORWARD);
138 const BOPTools_Pave& aPave2=aPB.Pave2();
141 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
142 aV2.Orientation(TopAbs_REVERSED);
144 if (aNbPaveBlocks==1) {
145 bIsNewVertex1=myDS->IsNewShape (nV1);
146 bIsNewVertex2=myDS->IsNewShape (nV2);
147 if (!bIsNewVertex1 && !bIsNewVertex2) {
153 BOPTools_Tools::MakeSplitEdge(aE, aV1, t1, aV2, t2, aESplit);
155 // Add Split Part of the Original Edge to the DS
156 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
158 anASSeq.SetNewSuccessor(nV1);
159 anASSeq.SetNewOrientation(aV1.Orientation());
161 anASSeq.SetNewSuccessor(nV2);
162 anASSeq.SetNewOrientation(aV2.Orientation());
164 if (anOri==TopAbs_INTERNAL) {
165 anASSeq.SetNewAncestor(i);
166 aESplit.Orientation(anOri);
169 myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
170 aNewShapeIndex=myDS->NumberOfInsertedShapes();
171 myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
173 // Fill Split Set for the Original Edge
174 aPB.SetEdge(aNewShapeIndex);
178 myIsDone=Standard_True;
180 //=======================================================================
181 // function: UpdateCommonBlocks
183 //=======================================================================
184 void NMTTools_PaveFiller::UpdateCommonBlocks()
186 myIsDone=Standard_False;
188 Standard_Integer nE, aNbS, nSp, nEx, nSpx;
189 NMTTools_ListIteratorOfListOfCommonBlock aCBIt;
190 BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
192 aNbS=myDS->NumberOfShapesOfTheObject();
194 for (nE=1; nE<=aNbS; ++nE) {
195 if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
198 if (BRep_Tool::Degenerated(TopoDS::Edge(myDS->Shape(nE)))){
202 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
203 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool (myDS->RefEdge(nE));
205 aCBIt.Initialize(aLCB);
206 for (; aCBIt.More(); aCBIt.Next()) {
207 NMTTools_CommonBlock& aCB=aCBIt.Value();
209 //modified by NIZNHY-PKV Wed Nov 8 15:59:46 2006f
210 // Among all PBs of aCB the first PB will be one
211 // that have max tolerance value
213 Standard_Real aTolEx, aTolExMax;
214 BOPTools_ListOfPaveBlock *pLPB, aLPBx;
217 pLPB=(BOPTools_ListOfPaveBlock *)&aCB.PaveBlocks();
218 aPBIt.Initialize(*pLPB);
219 for (; aPBIt.More(); aPBIt.Next()) {
220 const BOPTools_PaveBlock& aPBx=aPBIt.Value();
221 nEx=aPBx.OriginalEdge();
222 const TopoDS_Edge& aEx=TopoDS::Edge(myDS->Shape(nEx));
223 aTolEx=BRep_Tool::Tolerance(aEx);
224 if (aTolEx>aTolExMax) {
236 //modified by NIZNHY-PKV Wed Nov 8 15:59:50 2006t
238 BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
242 const BOPTools_ListOfPaveBlock& aCBLPB=aCB.PaveBlocks();
243 aPBIt.Initialize(aCBLPB);
244 for (; aPBIt.More(); aPBIt.Next()) {
245 BOPTools_PaveBlock& aPBx=aPBIt.Value();
246 nEx=aPBx.OriginalEdge();
251 nSpx=SplitIndex(aPBx);
258 //=======================================================================
259 // function: SplitIndex
261 //=======================================================================
262 Standard_Integer NMTTools_PaveFiller::SplitIndex(const BOPTools_PaveBlock& aPBx)const
264 Standard_Integer anOriginalEdge, anEdgeIndex=0;
266 anOriginalEdge=aPBx.OriginalEdge();
268 const BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(anOriginalEdge));
270 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
271 for (; anIt.More(); anIt.Next()) {
272 BOPTools_PaveBlock& aPB=anIt.Value();
273 if (aPB.IsEqual(aPBx)) {
274 anEdgeIndex=aPB.Edge();
280 //=======================================================================
281 // function: UpdatePaveBlocks
283 //=======================================================================
284 void NMTTools_PaveFiller::UpdatePaveBlocks()
286 myIsDone=Standard_False;
289 Standard_Integer i, aNbFFs, nF1, nF2, aNbF, nF, iRankF, nE, nV1, nV2, aNbPB;
290 Standard_Real aT1, aT2;
291 TColStd_IndexedMapOfInteger aMF, aME;
292 TopExp_Explorer aExp;
293 TopoDS_Vertex aV1, aV2;
295 BOPTools_Pave aPave1, aPave2;
296 BOPTools_PaveBlock aPB;
298 BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
300 aNbFFs=aFFs.Extent();
301 for (i=1; i<=aNbFFs; ++i) {
302 BOPTools_SSInterference& aFFi=aFFs(i);
303 aFFi.Indices(nF1, nF2);
309 for(i=1; i<=aNbF; ++i) {
311 iRankF=myDS->Rank(nF);
312 const TopoDS_Shape aF=myDS->Shape(nF);//mpv
313 aExp.Init(aF, TopAbs_EDGE);
314 for(; aExp.More(); aExp.Next()) {
315 aE=TopoDS::Edge(aExp.Current());
317 if (BRep_Tool::Degenerated(aE)) {
321 nE=myDS->ShapeIndex(aE, iRankF);
323 if (aME.Contains(nE)) {
328 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
333 TopExp::Vertices(aE, aV1, aV2);
335 nV1=myDS->ShapeIndex(aV1, iRankF);
336 aT1=BRep_Tool::Parameter(aV1, aE);
337 aPave1.SetIndex(nV1);
338 aPave1.SetParam(aT1);
340 nV2=myDS->ShapeIndex(aV2, iRankF);
341 aT2=BRep_Tool::Parameter(aV2, aE);
342 aPave2.SetIndex(nV2);
343 aPave2.SetParam(aT2);
346 aPB.SetOriginalEdge(nE);
347 aPB.SetPave1(aPave1);
348 aPB.SetPave2(aPave2);
355 // to treat Alone Vertices between faces
356 // Thu Sep 14 14:35:18 2006
357 // Contribution of Samtech www.samcef.com BEGIN
358 //=======================================================================
359 // function: MakeAloneVertices
361 //=======================================================================
362 void NMTTools_PaveFiller::MakeAloneVertices()
364 Standard_Integer i, aNbFFs, nF1, nF2, j, aNbPnts, nFx, aNbV;
365 Standard_Real aTolF1, aTolF2, aTolSum, aTolV;
366 TColStd_ListIteratorOfListOfInteger aIt;
367 TColStd_ListOfInteger aLI;
369 TopoDS_Compound aCompound;
371 TopTools_DataMapOfShapeListOfInteger aDMVFF, aDMVFF1;
372 TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger aItDMVFF;
373 TopTools_DataMapOfShapeShape aDMVV;
374 TopTools_DataMapOfIntegerShape aDMIV;
375 TopTools_DataMapOfShapeInteger aDMVI;
376 TopTools_DataMapIteratorOfDataMapOfShapeInteger aItDMVI;
377 TopTools_DataMapIteratorOfDataMapOfIntegerShape aItDMIV;
379 aBB.MakeCompound(aCompound);
381 myAloneVertices.Clear();
383 BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
385 // 1. Collect alone vertices from FFs
387 aNbFFs=aFFs.Extent();
388 for (i=1; i<=aNbFFs; ++i) {
389 BOPTools_SSInterference& aFFi=aFFs(i);
390 aFFi.Indices(nF1, nF2);
392 const TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));//mpv
393 const TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));//mpv
395 aTolF1=BRep_Tool::Tolerance(aF1);
396 aTolF2=BRep_Tool::Tolerance(aF2);
397 aTolSum=aTolF1+aTolF2;
403 const IntTools_SequenceOfPntOn2Faces& aSeqAlonePnts=aFFi.AlonePnts();
404 aNbPnts=aSeqAlonePnts.Length();
405 for (j=1; j<=aNbPnts; ++j) {
406 const gp_Pnt& aP=aSeqAlonePnts(j).P1().Pnt();
407 BOPTools_Tools::MakeNewVertex(aP, aTolSum, aV);
408 aDMVFF.Bind(aV, aLI);
409 aBB.Add(aCompound, aV);
417 // 2. Try to fuse alone vertices themselves;
418 FuseVertices(aCompound, aDMVV);
420 // if some are fused, replace them by new ones
421 aItDMVFF.Initialize(aDMVFF);
422 for (; aItDMVFF.More(); aItDMVFF.Next()) {
423 const TopoDS_Shape& aVx=aItDMVFF.Key();
424 const TColStd_ListOfInteger& aLIx=aItDMVFF.Value();
426 if (!aDMVV.IsBound(aVx)) {
427 aDMVFF1.Bind(aVx, aLIx);
430 const TopoDS_Shape& aVy=aDMVV.Find(aVx);
432 if (aDMVFF1.IsBound(aVy)) {
433 TColStd_ListOfInteger& aLIy=aDMVFF1.ChangeFind(aVy);
434 aIt.Initialize(aLIx);
435 for(; aIt.More(); aIt.Next()) {
441 aDMVFF1.Bind(aVy, aLIx);
447 // refine lists of faces in aDMVFF1;
448 aItDMVFF.Initialize(aDMVFF1);
449 for (; aItDMVFF.More(); aItDMVFF.Next()) {
450 TColStd_MapOfInteger aMIy;
451 TColStd_ListOfInteger aLIy;
453 const TopoDS_Shape& aVx=aItDMVFF.Key();
454 TColStd_ListOfInteger& aLIx=aDMVFF1.ChangeFind(aVx);
455 aIt.Initialize(aLIx);
456 for(; aIt.More(); aIt.Next()) {
465 //==================================
467 // 3. Collect vertices from DS
468 Standard_Integer aNbS, nV, nVSD, aNbVDS, i1, i2, aNbVSD;
470 aNbS=myDS->NumberOfShapesOfTheObject();
472 for (i=1; i<=aNbS; ++i) {
473 const TopoDS_Shape& aS=myDS->Shape(i);
474 if (aS.ShapeType() != TopAbs_VERTEX){
478 nVSD=FindSDVertex(i);
479 nV=(nVSD) ? nVSD : i;
480 const TopoDS_Shape& aVx=myDS->Shape(nV);
481 if (!aDMVI.IsBound(aVx)) {
486 i1=myDS->NumberOfSourceShapes()+1;
487 i2=myDS->NumberOfInsertedShapes();
488 for (i=i1; i<=i2; ++i) {
489 const TopoDS_Shape aS=myDS->Shape(i);//mpv
490 if (aS.ShapeType() != TopAbs_VERTEX){
493 if (!aDMVI.IsBound(aS)) {
498 // 4. Initialize BoundSortBox on aDMVI
500 Handle(Bnd_HArray1OfBox) aHAB;
501 Bnd_BoundSortBox aBSB;
503 aNbVDS=aDMVI.Extent();
504 aHAB=new Bnd_HArray1OfBox(1, aNbVDS);
506 aItDMVI.Initialize(aDMVI);
507 for (i=1; aItDMVI.More(); aItDMVI.Next(), ++i) {
511 aV=TopoDS::Vertex(aItDMVI.Key());
512 aTolV=BRep_Tool::Tolerance(aV);
514 BRepBndLib::Add(aV, aBox);
515 aHAB->SetValue(i, aBox);
519 aBSB.Initialize(aHAB);
522 aItDMVFF.Initialize(aDMVFF1);
523 for (; aItDMVFF.More(); aItDMVFF.Next()) {
526 const TColStd_ListOfInteger& aLIFF=aItDMVFF.Value();
527 aV=TopoDS::Vertex(aItDMVFF.Key());
529 aTolV=BRep_Tool::Tolerance(aV);
531 BRepBndLib::Add(aV, aBoxV);
533 const TColStd_ListOfInteger& aLIVSD=aBSB.Compare(aBoxV);
534 aNbVSD=aLIVSD.Extent();
536 // add new vertex in DS and update map myAloneVertices
537 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
539 myDS->InsertShapeAndAncestorsSuccessors(aV, anASSeq);
540 nV=myDS->NumberOfInsertedShapes();
542 aIt.Initialize(aLIFF);
543 for (; aIt.More(); aIt.Next()) {
545 if (myAloneVertices.Contains(nFx)) {
546 TColStd_IndexedMapOfInteger& aMVx=myAloneVertices.ChangeFromKey(nFx);
550 TColStd_IndexedMapOfInteger aMVx;
552 myAloneVertices.Add(nFx, aMVx);
559 Standard_Integer aNbF, aNbAV, nF, k;
560 NMTTools_IndexedDataMapOfIndexedMapOfInteger aMAVF;
562 aNbF=myAloneVertices.Extent();
567 // 1. fill map Alone Vertex/Face -> aMAVF
568 for (i=1; i<=aNbF; ++i) {
569 nF=myAloneVertices.FindKey(i);
570 const TColStd_IndexedMapOfInteger& aMAV=myAloneVertices(i);
572 for(j=1; j<=aNbAV; ++j) {
574 if (aMAVF.Contains(nV)) {
575 TColStd_IndexedMapOfInteger& aMF=aMAVF.ChangeFromKey(nV);
579 TColStd_IndexedMapOfInteger aMF;
586 // 2 Obtain pairs of faces
587 aNbAV=aMAVF.Extent();
588 for (i=1; i<=aNbAV; ++i) {
589 const TColStd_IndexedMapOfInteger& aMF=aMAVF(i);
591 for(j=1; j<aNbF; ++j) {
593 for(k=j+1; k<=aNbF; ++k) {
595 myIP->Add(nF1, nF2, Standard_True, NMTDS_TI_FF);
602 //=======================================================================
603 // function: AloneVertices
605 //=======================================================================
606 const NMTTools_IndexedDataMapOfIndexedMapOfInteger& NMTTools_PaveFiller::AloneVertices()const
608 return myAloneVertices;
610 //=======================================================================
611 // function: FuseVertices
613 //=======================================================================
614 void NMTTools_PaveFiller::FuseVertices(const TopoDS_Shape& aCompound,
615 TopTools_DataMapOfShapeShape& aDMVV)const
617 Standard_Integer i, aNbVV, n1, n2, nX;
618 NMTTools_PaveFiller tPF;
620 tPF.SetCompositeShape(aCompound);
625 //tPF.PerformNewVertices(); //qq
627 NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
628 NMTDS_InterfPool& tInterfPool=*(tPF.IP());
629 BOPTools_CArray1OfVVInterference& aVVt=tInterfPool.VVInterferences();
632 for (i=1; i<=aNbVV; ++i) {
633 const BOPTools_VVInterference& aVV=aVVt(i);
637 const TopoDS_Shape& aV1=tDS.Shape(n1);
638 const TopoDS_Shape& aV2=tDS.Shape(n2);
639 const TopoDS_Shape& aVx=tDS.Shape(nX);
640 aDMVV.Bind(aV1, aVx);
641 aDMVV.Bind(aV2, aVx);
645 // Contribution of Samtech www.samcef.com END