0028259: Method MakeBlocksCnx is duplicated in two different places in BOPAlgo
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_10.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18 #include <BOPAlgo_PaveFiller.hxx>
19
20 #include <Precision.hxx>
21
22 #include <gp_Pnt.hxx>
23 #include <Bnd_Box.hxx>
24
25 #include <TopoDS_Iterator.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Edge.hxx>
28
29 #include <BRep_Tool.hxx>
30 #include <BRep_Builder.hxx>
31 #include <BRepBndLib.hxx>
32
33 #include <BOPDS_ShapeInfo.hxx>
34 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
35 #include <BOPDS_MapOfCommonBlock.hxx>
36 #include <BOPDS_ListOfPaveBlock.hxx>
37 #include <BOPDS_CommonBlock.hxx>
38 #include <BOPDS_DS.hxx>
39
40 //=======================================================================
41 //function : SetNonDestructive
42 //purpose  : 
43 //=======================================================================
44 void BOPAlgo_PaveFiller::SetNonDestructive() 
45 {
46   if (!myIsPrimary || myNonDestructive) {
47     return;
48   }
49   //
50   Standard_Boolean bFlag;
51   BOPCol_ListIteratorOfListOfShape aItLS;
52   //
53   bFlag=Standard_False;
54   aItLS.Initialize(myArguments);
55   for(; aItLS.More() && (!bFlag); aItLS.Next()) {
56     const TopoDS_Shape& aS=aItLS.Value();
57     bFlag=aS.Locked();
58   }
59   myNonDestructive=bFlag;
60 }
61 //=======================================================================
62 //function : UpdateEdgeTolerance
63 //purpose  : 
64 //=======================================================================
65 void BOPAlgo_PaveFiller::UpdateEdgeTolerance (const Standard_Integer nE,
66                                               const Standard_Real aTol)
67 {
68   Standard_Boolean bIsNewShape, bHasShapeSD;
69   Standard_Integer nV, nVx;
70   Standard_Real aTolV;
71   BRep_Builder aBB;
72   BOPCol_ListIteratorOfListOfInteger aIt;
73   //
74   BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
75   const BOPCol_ListOfInteger& aLI=aSIE.SubShapes();
76   //
77   if (myNonDestructive) {
78     bIsNewShape=myDS->IsNewShape(nE);
79     if (!bIsNewShape) {
80       return;
81     }
82     //
83     aIt.Initialize(aLI);
84     for (; aIt.More(); aIt.Next()) {
85       nV = aIt.Value();
86       bHasShapeSD=myDS->HasShapeSD(nV, nVx);
87       if (bHasShapeSD) {
88         continue;
89       }
90       bIsNewShape=myDS->IsNewShape(nV);
91       if (!bIsNewShape) {
92         return;
93       }
94     }
95   }
96   //
97   const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
98   aBB.UpdateEdge(aE, aTol);
99   Bnd_Box& aBoxE=aSIE.ChangeBox();
100   BRepBndLib::Add(aE, aBoxE);
101   aBoxE.SetGap(aBoxE.GetGap() + Precision::Confusion());
102   //
103   aIt.Initialize(aLI);
104   for (; aIt.More(); aIt.Next()) {
105     nV = aIt.Value();
106     bHasShapeSD=myDS->HasShapeSD(nV, nVx);
107     if (bHasShapeSD) {
108       nV=nVx;
109     }
110     const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
111     aTolV = BRep_Tool::Tolerance(aV);
112     if (aTolV < aTol) {
113       aBB.UpdateVertex(aV, aTol);
114       BOPDS_ShapeInfo& aSIV = myDS->ChangeShapeInfo(nV);
115       Bnd_Box& aBoxV = aSIV.ChangeBox();
116       BRepBndLib::Add(aV, aBoxV);
117       aBoxV.SetGap(aBoxV.GetGap() + Precision::Confusion());
118     }
119   }
120 }
121 //=======================================================================
122 //function : UpdateVertex
123 //purpose  : 
124 //=======================================================================
125 Standard_Integer BOPAlgo_PaveFiller::UpdateVertex
126   (const Standard_Integer nV,
127    const Standard_Real aTolNew)
128 {
129   Standard_Integer nVNew;
130   Standard_Real aTolV;
131   BRep_Builder aBB;
132   
133   nVNew = nV;
134   if (myDS->IsNewShape(nVNew) || 
135       myDS->HasShapeSD(nV, nVNew) ||
136       !myNonDestructive) {
137     // nV is a new vertex, it has SD or non-destructive mode is not in force
138     const TopoDS_Vertex& aVSD = *(TopoDS_Vertex*)&myDS->Shape(nVNew);
139     aTolV = BRep_Tool::Tolerance(aVSD);
140     if (aTolV < aTolNew) {
141       aBB.UpdateVertex(aVSD, aTolNew);
142       BOPDS_ShapeInfo& aSIV = myDS->ChangeShapeInfo(nVNew);
143       Bnd_Box& aBoxV = aSIV.ChangeBox();
144       BRepBndLib::Add(aVSD, aBoxV);
145       aBoxV.SetGap(aBoxV.GetGap() + Precision::Confusion());
146     }
147     return nVNew;
148   }
149   //
150   // nV is old vertex
151   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
152   aTolV = BRep_Tool::Tolerance(aV);
153   //
154   // create new vertex
155   TopoDS_Vertex aVNew;
156   gp_Pnt aPV = BRep_Tool::Pnt(aV);
157   aBB.MakeVertex(aVNew, aPV, Max(aTolV, aTolNew));
158   //
159   // append new vertex to DS
160   BOPDS_ShapeInfo aSIV;
161   aSIV.SetShapeType(TopAbs_VERTEX);
162   aSIV.SetShape(aVNew);
163   nVNew = myDS->Append(aSIV);
164   //
165   // bounding box for the new vertex
166   BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(nVNew);
167   Bnd_Box& aBoxDS = aSIDS.ChangeBox();
168   BRepBndLib::Add(aVNew, aBoxDS);
169   aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
170   //
171   // add vertex to SD map
172   myDS->AddShapeSD(nV, nVNew);
173   //
174   myDS->InitPaveBlocksForVertex(nV);
175   //
176   return nVNew;
177 }
178 //=======================================================================
179 //function : UpdatePaveBlocksWithSDVertices
180 //purpose  : 
181 //=======================================================================
182 void BOPAlgo_PaveFiller::UpdatePaveBlocksWithSDVertices()
183 {
184   myDS->UpdatePaveBlocksWithSDVertices();
185 }
186 //=======================================================================
187 //function : UpdateCommonBlocksWithSDVertices
188 //purpose  : 
189 //=======================================================================
190 void BOPAlgo_PaveFiller::UpdateCommonBlocksWithSDVertices()
191 {
192   if (!myNonDestructive) {
193     UpdatePaveBlocksWithSDVertices();
194     return;
195   }
196   Standard_Integer aNbPBP;
197   //
198   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
199   aNbPBP=aPBP.Extent();
200   if(!aNbPBP) {
201     return;
202   }
203   //
204   Standard_Integer i, nV1, nV2;
205   Standard_Real aTolV;
206   BOPDS_MapOfCommonBlock aMCB;
207   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
208   Handle(BOPDS_PaveBlock) aPB;
209   // 
210   aTolV = Precision::Confusion();
211   //
212   for (i=0; i<aNbPBP; ++i) {
213     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
214     aItPB.Initialize(aLPB);
215     for (; aItPB.More(); aItPB.Next()) {
216       aPB=aItPB.Value();
217       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
218       if (aCB.IsNull()) {
219         continue;
220       }
221       //
222       if (aMCB.Add(aCB)) {
223         aPB->Indices(nV1, nV2);
224         UpdateVertex(nV1, aTolV);
225         UpdateVertex(nV2, aTolV);
226         myDS->UpdateCommonBlockWithSDVertices(aCB);
227       }
228     }
229   }
230   UpdatePaveBlocksWithSDVertices();
231 }
232
233 namespace
234 {
235   //=======================================================================
236   //function : UpdateInterfsWithSDVertices
237   //purpose  : 
238   //=======================================================================
239   template <class InterfType>
240   void UpdateIntfsWithSDVertices(BOPDS_PDS theDS, BOPCol_NCVector<InterfType>& theInterfs)
241   {
242     for (Standard_Integer i = 0; i < theInterfs.Length(); i++)
243     {
244       InterfType& anIntf = theInterfs(i);
245       Standard_Integer anInd;
246       if (anIntf.HasIndexNew(anInd))
247       {
248         Standard_Integer anIndSD;
249         if (theDS->HasShapeSD(anInd, anIndSD))
250         {
251           anIntf.SetIndexNew(anIndSD);
252         }
253       }
254     }
255   }
256 }
257
258 //=======================================================================
259 //function : UpdateInterfsWithSDVertices
260 //purpose  : 
261 //=======================================================================
262 void BOPAlgo_PaveFiller::UpdateInterfsWithSDVertices()
263 {
264   UpdateIntfsWithSDVertices(myDS, myDS->InterfVV());
265   UpdateIntfsWithSDVertices(myDS, myDS->InterfVE());
266   UpdateIntfsWithSDVertices(myDS, myDS->InterfVF());
267   UpdateIntfsWithSDVertices(myDS, myDS->InterfEE());
268   UpdateIntfsWithSDVertices(myDS, myDS->InterfEF());
269 }