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_7.cxx
21 // Created: Thu Dec 18 15:14:55 2003
22 // Author: Peter KURNEV
26 #include <NMTTools_PaveFiller.ixx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopoDS_Edge.hxx>
32 #include <NMTDS_ShapesDataStructure.hxx>
33 #include <TopAbs_Orientation.hxx>
34 #include <BOPTools_ListOfPaveBlock.hxx>
35 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
36 #include <BOPTools_PaveBlock.hxx>
37 #include <BOPTools_Pave.hxx>
38 #include <BOPTools_Tools.hxx>
39 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
40 #include <BRep_Tool.hxx>
41 #include <NMTTools_ListIteratorOfListOfCommonBlock.hxx>
42 #include <BOPTools_SSInterference.hxx>
43 #include <BOPTools_CArray1OfSSInterference.hxx>
44 #include <TopExp_Explorer.hxx>
45 #include <TopoDS_Shape.hxx>
47 #include <TColStd_IndexedMapOfInteger.hxx>
50 #include <IntTools_SequenceOfPntOn2Faces.hxx>
51 #include <IntTools_PntOnFace.hxx>
52 #include <IntTools_PntOn2Faces.hxx>
53 #include <BOPTools_Tools.hxx>
54 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
55 #include <TColStd_ListOfInteger.hxx>
56 #include <TopoDS_Compound.hxx>
57 #include <BRep_Builder.hxx>
58 #include <BOPTools_CArray1OfVVInterference.hxx>
59 #include <BOPTools_VVInterference.hxx>
60 #include <TopTools_DataMapOfShapeShape.hxx>
61 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
62 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger.hxx>
63 #include <TColStd_MapOfInteger.hxx>
64 #include <TColStd_ListIteratorOfListOfInteger.hxx>
65 #include <TopTools_DataMapOfIntegerShape.hxx>
66 #include <Bnd_HArray1OfBox.hxx>
67 #include <Bnd_BoundSortBox.hxx>
68 #include <Bnd_Box.hxx>
69 #include <BRepBndLib.hxx>
70 #include <TopTools_DataMapIteratorOfDataMapOfIntegerShape.hxx>
71 #include <TopTools_DataMapOfShapeInteger.hxx>
72 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
73 #include <TopTools_DataMapOfShapeInteger.hxx>
74 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
76 // Modified Thu Sep 14 14:35:18 2006
77 // Contribution of Samtech www.samcef.com BEGIN
79 void FuseVertices(const TopoDS_Shape& aCompound,
80 TopTools_DataMapOfShapeShape& aDMVV);
81 // Contribution of Samtech www.samcef.com END
83 //=======================================================================
84 // function: MakeSplitEdges
86 //=======================================================================
87 void NMTTools_PaveFiller::MakeSplitEdges()
89 myIsDone=Standard_False;
91 Standard_Boolean bIsNewVertex1, bIsNewVertex2;
92 Standard_Integer i, aNbS, nV1, nV2, aNbPaveBlocks, aNewShapeIndex;
94 TopAbs_Orientation anOri;
95 TopoDS_Edge aE, aESplit;
96 TopoDS_Vertex aV1, aV2;
98 aNbS=myDS->NumberOfShapesOfTheObject();
99 for (i=1; i<=aNbS; ++i) {
100 if (myDS->GetShapeType(i) != TopAbs_EDGE)
104 aE=TopoDS::Edge(myDS->Shape(i));
105 if (BRep_Tool::Degenerated(aE)){
109 anOri=aE.Orientation();
110 aE.Orientation(TopAbs_FORWARD);
112 // Making Split Edges
114 // Split Set for the Original Edge i
115 BOPTools_ListOfPaveBlock& aSplitEdges=mySplitShapesPool(myDS->RefEdge(i));
116 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplitEdges);
118 aNbPaveBlocks=aSplitEdges.Extent();
120 for (; aPBIt.More(); aPBIt.Next()) {
121 BOPTools_PaveBlock& aPB=aPBIt.Value();
123 const BOPTools_Pave& aPave1=aPB.Pave1();
126 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
127 aV1.Orientation(TopAbs_FORWARD);
129 const BOPTools_Pave& aPave2=aPB.Pave2();
132 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
133 aV2.Orientation(TopAbs_REVERSED);
135 if (aNbPaveBlocks==1) {
136 bIsNewVertex1=myDS->IsNewShape (nV1);
137 bIsNewVertex2=myDS->IsNewShape (nV2);
138 if (!bIsNewVertex1 && !bIsNewVertex2) {
144 BOPTools_Tools::MakeSplitEdge(aE, aV1, t1, aV2, t2, aESplit);
146 // Add Split Part of the Original Edge to the DS
147 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
149 anASSeq.SetNewSuccessor(nV1);
150 anASSeq.SetNewOrientation(aV1.Orientation());
152 anASSeq.SetNewSuccessor(nV2);
153 anASSeq.SetNewOrientation(aV2.Orientation());
155 if (anOri==TopAbs_INTERNAL) {
156 anASSeq.SetNewAncestor(i);
157 aESplit.Orientation(anOri);
160 myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
161 aNewShapeIndex=myDS->NumberOfInsertedShapes();
162 myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
164 // Fill Split Set for the Original Edge
165 aPB.SetEdge(aNewShapeIndex);
169 myIsDone=Standard_True;
171 //=======================================================================
172 // function: UpdateCommonBlocks
174 //=======================================================================
175 void NMTTools_PaveFiller::UpdateCommonBlocks()
177 myIsDone=Standard_False;
179 Standard_Integer nE, aNbS, nSp, nEx, nSpx;
180 NMTTools_ListIteratorOfListOfCommonBlock aCBIt;
181 BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
183 aNbS=myDS->NumberOfShapesOfTheObject();
185 for (nE=1; nE<=aNbS; ++nE) {
186 if (myDS->GetShapeType(nE)!=TopAbs_EDGE){
189 if (BRep_Tool::Degenerated(TopoDS::Edge(myDS->Shape(nE)))){
193 NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
194 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool (myDS->RefEdge(nE));
196 aCBIt.Initialize(aLCB);
197 for (; aCBIt.More(); aCBIt.Next()) {
198 NMTTools_CommonBlock& aCB=aCBIt.Value();
200 //modified by NIZNHY-PKV Wed Nov 8 15:59:46 2006f
201 // Among all PBs of aCB the first PB will be one
202 // that have max tolerance value
204 Standard_Real aTolEx, aTolExMax;
205 BOPTools_ListOfPaveBlock *pLPB, aLPBx;
208 pLPB=(BOPTools_ListOfPaveBlock *)&aCB.PaveBlocks();
209 aPBIt.Initialize(*pLPB);
210 for (; aPBIt.More(); aPBIt.Next()) {
211 const BOPTools_PaveBlock& aPBx=aPBIt.Value();
212 nEx=aPBx.OriginalEdge();
213 const TopoDS_Edge& aEx=TopoDS::Edge(myDS->Shape(nEx));
214 aTolEx=BRep_Tool::Tolerance(aEx);
215 if (aTolEx>aTolExMax) {
227 //modified by NIZNHY-PKV Wed Nov 8 15:59:50 2006t
229 BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
233 const BOPTools_ListOfPaveBlock& aCBLPB=aCB.PaveBlocks();
234 aPBIt.Initialize(aCBLPB);
235 for (; aPBIt.More(); aPBIt.Next()) {
236 BOPTools_PaveBlock& aPBx=aPBIt.Value();
237 nEx=aPBx.OriginalEdge();
242 nSpx=SplitIndex(aPBx);
249 //=======================================================================
250 // function: SplitIndex
252 //=======================================================================
253 Standard_Integer NMTTools_PaveFiller::SplitIndex(const BOPTools_PaveBlock& aPBx)const
255 Standard_Integer anOriginalEdge, anEdgeIndex=0;
257 anOriginalEdge=aPBx.OriginalEdge();
259 const BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(anOriginalEdge));
261 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
262 for (; anIt.More(); anIt.Next()) {
263 BOPTools_PaveBlock& aPB=anIt.Value();
264 if (aPB.IsEqual(aPBx)) {
265 anEdgeIndex=aPB.Edge();
271 //=======================================================================
272 // function: UpdatePaveBlocks
274 //=======================================================================
275 void NMTTools_PaveFiller::UpdatePaveBlocks()
277 myIsDone=Standard_False;
280 Standard_Integer i, aNbFFs, nF1, nF2, aNbF, nF, iRankF, nE, nV1, nV2, aNbPB;
281 Standard_Real aT1, aT2;
282 TColStd_IndexedMapOfInteger aMF, aME;
283 TopExp_Explorer aExp;
284 TopoDS_Vertex aV1, aV2;
286 BOPTools_Pave aPave1, aPave2;
287 BOPTools_PaveBlock aPB;
289 BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
291 aNbFFs=aFFs.Extent();
292 for (i=1; i<=aNbFFs; ++i) {
293 BOPTools_SSInterference& aFFi=aFFs(i);
294 aFFi.Indices(nF1, nF2);
300 for(i=1; i<=aNbF; ++i) {
302 iRankF=myDS->Rank(nF);
303 const TopoDS_Shape aF=myDS->Shape(nF);//mpv
304 aExp.Init(aF, TopAbs_EDGE);
305 for(; aExp.More(); aExp.Next()) {
306 aE=TopoDS::Edge(aExp.Current());
308 if (BRep_Tool::Degenerated(aE)) {
312 nE=myDS->ShapeIndex(aE, iRankF);
314 if (aME.Contains(nE)) {
319 BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
324 TopExp::Vertices(aE, aV1, aV2);
326 nV1=myDS->ShapeIndex(aV1, iRankF);
327 aT1=BRep_Tool::Parameter(aV1, aE);
328 aPave1.SetIndex(nV1);
329 aPave1.SetParam(aT1);
331 nV2=myDS->ShapeIndex(aV2, iRankF);
332 aT2=BRep_Tool::Parameter(aV2, aE);
333 aPave2.SetIndex(nV2);
334 aPave2.SetParam(aT2);
337 aPB.SetOriginalEdge(nE);
338 aPB.SetPave1(aPave1);
339 aPB.SetPave2(aPave2);
346 // to treat Alone Vertices between faces
347 // Thu Sep 14 14:35:18 2006
348 // Contribution of Samtech www.samcef.com BEGIN
349 //=======================================================================
350 // function: MakeAloneVertices
352 //=======================================================================
353 void NMTTools_PaveFiller::MakeAloneVertices()
355 Standard_Integer i, aNbFFs, nF1, nF2, j, aNbPnts, nFx, aNbV;
356 Standard_Real aTolF1, aTolF2, aTolSum, aTolV;
357 TColStd_ListIteratorOfListOfInteger aIt;
358 TColStd_ListOfInteger aLI;
360 TopoDS_Compound aCompound;
362 TopTools_DataMapOfShapeListOfInteger aDMVFF, aDMVFF1;
363 TopTools_DataMapIteratorOfDataMapOfShapeListOfInteger aItDMVFF;
364 TopTools_DataMapOfShapeShape aDMVV;
365 TopTools_DataMapOfIntegerShape aDMIV;
366 TopTools_DataMapOfShapeInteger aDMVI;
367 TopTools_DataMapIteratorOfDataMapOfShapeInteger aItDMVI;
368 TopTools_DataMapIteratorOfDataMapOfIntegerShape aItDMIV;
370 aBB.MakeCompound(aCompound);
372 myAloneVertices.Clear();
374 BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
376 // 1. Collect alone vertices from FFs
378 aNbFFs=aFFs.Extent();
379 for (i=1; i<=aNbFFs; ++i) {
380 BOPTools_SSInterference& aFFi=aFFs(i);
381 aFFi.Indices(nF1, nF2);
383 const TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));//mpv
384 const TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));//mpv
386 aTolF1=BRep_Tool::Tolerance(aF1);
387 aTolF2=BRep_Tool::Tolerance(aF2);
388 aTolSum=aTolF1+aTolF2;
394 const IntTools_SequenceOfPntOn2Faces& aSeqAlonePnts=aFFi.AlonePnts();
395 aNbPnts=aSeqAlonePnts.Length();
396 for (j=1; j<=aNbPnts; ++j) {
397 const gp_Pnt& aP=aSeqAlonePnts(j).P1().Pnt();
398 BOPTools_Tools::MakeNewVertex(aP, aTolSum, aV);
399 aDMVFF.Bind(aV, aLI);
400 aBB.Add(aCompound, aV);
408 // 2. Try to fuse alone vertices themselves;
409 FuseVertices(aCompound, aDMVV);
411 // if some are fused, replace them by new ones
412 aItDMVFF.Initialize(aDMVFF);
413 for (; aItDMVFF.More(); aItDMVFF.Next()) {
414 const TopoDS_Shape& aVx=aItDMVFF.Key();
415 const TColStd_ListOfInteger& aLIx=aItDMVFF.Value();
417 if (!aDMVV.IsBound(aVx)) {
418 aDMVFF1.Bind(aVx, aLIx);
421 const TopoDS_Shape& aVy=aDMVV.Find(aVx);
423 if (aDMVFF1.IsBound(aVy)) {
424 TColStd_ListOfInteger& aLIy=aDMVFF1.ChangeFind(aVy);
425 aIt.Initialize(aLIx);
426 for(; aIt.More(); aIt.Next()) {
432 aDMVFF1.Bind(aVy, aLIx);
438 // refine lists of faces in aDMVFF1;
439 aItDMVFF.Initialize(aDMVFF1);
440 for (; aItDMVFF.More(); aItDMVFF.Next()) {
441 TColStd_MapOfInteger aMIy;
442 TColStd_ListOfInteger aLIy;
444 const TopoDS_Shape& aVx=aItDMVFF.Key();
445 TColStd_ListOfInteger& aLIx=aDMVFF1.ChangeFind(aVx);
446 aIt.Initialize(aLIx);
447 for(; aIt.More(); aIt.Next()) {
456 //==================================
458 // 3. Collect vertices from DS
459 Standard_Integer aNbS, nV, nVSD, aNbVDS, i1, i2, aNbVSD;
461 aNbS=myDS->NumberOfShapesOfTheObject();
463 for (i=1; i<=aNbS; ++i) {
464 const TopoDS_Shape& aS=myDS->Shape(i);
465 if (aS.ShapeType() != TopAbs_VERTEX){
469 nVSD=FindSDVertex(i);
470 nV=(nVSD) ? nVSD : i;
471 const TopoDS_Shape& aVx=myDS->Shape(nV);
472 if (!aDMVI.IsBound(aVx)) {
477 i1=myDS->NumberOfSourceShapes()+1;
478 i2=myDS->NumberOfInsertedShapes();
479 for (i=i1; i<=i2; ++i) {
480 const TopoDS_Shape aS=myDS->Shape(i);//mpv
481 if (aS.ShapeType() != TopAbs_VERTEX){
484 if (!aDMVI.IsBound(aS)) {
489 // 4. Initialize BoundSortBox on aDMVI
491 Handle(Bnd_HArray1OfBox) aHAB;
492 Bnd_BoundSortBox aBSB;
494 aNbVDS=aDMVI.Extent();
495 aHAB=new Bnd_HArray1OfBox(1, aNbVDS);
497 aItDMVI.Initialize(aDMVI);
498 for (i=1; aItDMVI.More(); aItDMVI.Next(), ++i) {
502 aV=TopoDS::Vertex(aItDMVI.Key());
503 aTolV=BRep_Tool::Tolerance(aV);
505 BRepBndLib::Add(aV, aBox);
506 aHAB->SetValue(i, aBox);
510 aBSB.Initialize(aHAB);
513 aItDMVFF.Initialize(aDMVFF1);
514 for (; aItDMVFF.More(); aItDMVFF.Next()) {
517 const TColStd_ListOfInteger& aLIFF=aItDMVFF.Value();
518 aV=TopoDS::Vertex(aItDMVFF.Key());
520 aTolV=BRep_Tool::Tolerance(aV);
522 BRepBndLib::Add(aV, aBoxV);
524 const TColStd_ListOfInteger& aLIVSD=aBSB.Compare(aBoxV);
525 aNbVSD=aLIVSD.Extent();
527 // add new vertex in DS and update map myAloneVertices
528 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
530 myDS->InsertShapeAndAncestorsSuccessors(aV, anASSeq);
531 nV=myDS->NumberOfInsertedShapes();
533 aIt.Initialize(aLIFF);
534 for (; aIt.More(); aIt.Next()) {
536 if (myAloneVertices.Contains(nFx)) {
537 TColStd_IndexedMapOfInteger& aMVx=myAloneVertices.ChangeFromKey(nFx);
541 TColStd_IndexedMapOfInteger aMVx;
543 myAloneVertices.Add(nFx, aMVx);
549 //=======================================================================
550 // function: AloneVertices
552 //=======================================================================
553 const NMTTools_IndexedDataMapOfIndexedMapOfInteger& NMTTools_PaveFiller::AloneVertices()const
555 return myAloneVertices;
557 //=======================================================================
558 // function: FuseVertices
560 //=======================================================================
561 void FuseVertices(const TopoDS_Shape& aCompound,
562 TopTools_DataMapOfShapeShape& aDMVV)
564 Standard_Integer i, aNbVV, n1, n2, nX;
565 NMTDS_ShapesDataStructure tDS;
567 tDS.SetCompositeShape(aCompound);
570 BOPTools_InterferencePool tInterfPool(tDS);
571 NMTTools_PaveFiller tPaveFiller(tInterfPool);
575 tPaveFiller.PerformVV();
576 tPaveFiller.PerformNewVertices();
578 const BOPTools_CArray1OfVVInterference& aVVt=tInterfPool.VVInterfs();
581 for (i=1; i<=aNbVV; ++i) {
582 const BOPTools_VVInterference& aVV=aVVt(i);
586 const TopoDS_Shape& aV1=tDS.Shape(n1);
587 const TopoDS_Shape& aV2=tDS.Shape(n2);
588 const TopoDS_Shape& aVx=tDS.Shape(nX);
589 aDMVV.Bind(aV1, aVx);
590 aDMVV.Bind(aV2, aVx);
594 // Contribution of Samtech www.samcef.com END