0024428: Implementation of LGPL license
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_7.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
10 // under the terms of the GNU Lesser General Public 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.ixx>
19
20 #include <NCollection_IncAllocator.hxx>
21
22 #include <TopoDS_Vertex.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Face.hxx>
25
26 #include <BRepBndLib.hxx>
27
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30
31 #include <TopExp.hxx>
32
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom2d_Curve.hxx>
36
37 #include <BOPTools_AlgoTools.hxx>
38 #include <BOPTools_AlgoTools2D.hxx>
39
40 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
41 #include <BOPDS_ListOfPaveBlock.hxx>
42 #include <BOPDS_PaveBlock.hxx>
43 #include <BOPDS_CommonBlock.hxx>
44 #include <BOPDS_Pave.hxx>
45 #include <BOPDS_ShapeInfo.hxx>
46 #include <BOPDS_MapOfPaveBlock.hxx>
47 #include <BOPDS_VectorOfInterfFF.hxx>
48 #include <BOPDS_Interf.hxx>
49 #include <BOPDS_VectorOfCurve.hxx>
50 #include <BOPDS_VectorOfFaceInfo.hxx>
51 #include <BOPDS_FaceInfo.hxx>
52 #include <BOPDS_MapOfPaveBlock.hxx>
53 #include <BOPDS_Curve.hxx>
54
55 static void UpdateVertices(const TopoDS_Edge& aE, 
56                            const TopoDS_Face& aF);
57
58 //=======================================================================
59 // function: MakeSplitEdges
60 // purpose: 
61 //=======================================================================
62   void BOPAlgo_PaveFiller::MakeSplitEdges()
63 {
64   Standard_Integer aNbPBP;
65   //
66   myErrorStatus=0;
67   //
68   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
69   aNbPBP=aPBP.Extent();
70   if(!aNbPBP) {
71     return;
72   }
73   //
74   Standard_Boolean bCB, bV1, bV2;
75   Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, nOrE;
76   Standard_Real aT1, aT2;
77   Handle(NCollection_IncAllocator) aAllocator;
78   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
79   Handle(BOPDS_PaveBlock) aPB, aPBx;
80   //-----------------------------------------------------scope f
81   //
82   aAllocator=new NCollection_IncAllocator();
83   //
84   BOPDS_MapOfPaveBlock aMPB(100,aAllocator);
85   //
86   for (i=0; i<aNbPBP; ++i) {
87     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
88     //
89     aNbPB=aLPB.Extent();
90     //DEBf
91     if (aNbPB) {
92       aPBx=aLPB.First();
93       nOrE=aPBx->OriginalEdge();
94     }
95     //DEBt
96     if (aNbPB==1) {
97       aPB=aLPB.First();
98       aPB->Indices(nV1, nV2);
99       bV1=myDS->IsNewShape(nV1);
100       bV2=myDS->IsNewShape(nV2);
101       //
102       if (!(bV1 || bV2)) {
103         nE=aPB->OriginalEdge();
104         aPB->SetEdge(nE);
105         continue;
106       }
107     }
108     //
109     aItPB.Initialize(aLPB);
110     for (; aItPB.More(); aItPB.Next()) {
111       aPB=aItPB.Value();
112       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
113       bCB=!aCB.IsNull();
114       if (bCB) {
115         myDS->SortPaveBlocks(aCB);
116         aPB=aCB->PaveBlock1();
117       }
118       //
119       if (aMPB.Add(aPB)) {
120         nE=aPB->OriginalEdge();
121         aPB->Indices(nV1, nV2);
122         aPB->Range(aT1, aT2);
123         //
124         nSp = SplitEdge(nE, nV1, aT1, nV2, aT2);
125         //
126         if (bCB) {
127           aCB->SetEdge(nSp);
128         }
129         else {
130           aPB->SetEdge(nSp);
131         }
132       }// if (aMPB.Add(aPB)) {
133     }// for (; aItPB.More(); aItPB.Next()) {
134   }// for (i=0; i<aNbPBP; ++i) {
135   //
136   //-----------------------------------------------------scope t
137   aMPB.Clear();
138   aAllocator.Nullify();
139 }
140
141 //=======================================================================
142 // function: SplitEdge
143 // purpose: 
144 //=======================================================================
145 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
146                                                const Standard_Integer nV1,
147                                                const Standard_Real aT1, 
148                                                const Standard_Integer nV2, 
149                                                const Standard_Real aT2)
150 {
151   Standard_Integer nSp;
152   TopoDS_Vertex aV1, aV2;
153   TopoDS_Edge aE, aSp;
154   BOPDS_ShapeInfo aSI;
155   //
156   aSI.SetShapeType(TopAbs_EDGE);
157   //
158   aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
159   aE.Orientation(TopAbs_FORWARD);
160   //
161   aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
162   aV1.Orientation(TopAbs_FORWARD); 
163   //
164   aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
165   aV2.Orientation(TopAbs_REVERSED); 
166   //
167   BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
168   //
169   aSI.SetShape(aSp);
170   //
171   Bnd_Box& aBox=aSI.ChangeBox();
172   BRepBndLib::Add(aSp, aBox);
173   //
174   nSp=myDS->Append(aSI);
175   return nSp;
176 }
177
178 //=======================================================================
179 // function: MakePCurves
180 // purpose: 
181 //=======================================================================
182   void BOPAlgo_PaveFiller::MakePCurves()
183 {
184   Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI;
185   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
186   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
187   TopoDS_Face aF1F, aF2F;
188   //
189   myErrorStatus=0;
190   //
191   // 1. Process Common Blocks 
192   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
193   //
194   aNbFI=aFIP.Extent();
195   for (i=0; i<aNbFI; ++i) {
196     const BOPDS_FaceInfo& aFI=aFIP(i);
197     nF1=aFI.Index();
198     //
199     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
200     aF1F.Orientation(TopAbs_FORWARD);
201     // In
202     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
203     aItMPB.Initialize(aMPBIn);
204     for(; aItMPB.More(); aItMPB.Next()) {
205       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
206       nE=aPB->Edge();
207       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
208       //
209       BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
210     }
211     // On
212     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
213     aItMPB.Initialize(aMPBOn);
214     for(; aItMPB.More(); aItMPB.Next()) {
215       const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
216       if (myDS->IsCommonBlockOnEdge(aPB)) {
217         nE=aPB->Edge();
218         const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
219         //
220         BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
221       }
222     }
223   }
224   //
225   if (!mySectionAttribute.PCurveOnS1() && 
226       !mySectionAttribute.PCurveOnS2()) {
227     return;
228   }
229   //
230   // 2. Process section edges
231   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
232   aNbFF=aFFs.Extent();
233   for (i=0; i<aNbFF; ++i) {
234     const BOPDS_InterfFF& aFF=aFFs(i);
235     aFF.Indices(nF1, nF2);
236     //
237     aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
238     aF1F.Orientation(TopAbs_FORWARD);
239     aF2F=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
240     aF2F.Orientation(TopAbs_FORWARD);
241     //
242     const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
243     aNbC=aVNC.Extent();
244     for (k=0; k<aNbC; ++k) {
245       const BOPDS_Curve& aNC=aVNC(k);
246       const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
247       aItLPB.Initialize(aLPB);
248       for(; aItLPB.More(); aItLPB.Next()) {
249         const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
250         nE=aPB->Edge();
251         const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
252         //
253         if (mySectionAttribute.PCurveOnS1()) {
254           BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
255           UpdateVertices(aE, aF1F);
256         }
257         //
258         if (mySectionAttribute.PCurveOnS2()) {
259           BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF2F);
260           UpdateVertices(aE, aF2F);
261         }
262       }
263     }
264   }
265 }
266
267 //=======================================================================
268 // function: RefineFaceInfoOn
269 // purpose: 
270 //=======================================================================
271   void BOPAlgo_PaveFiller::RefineFaceInfoOn() 
272 {
273   Standard_Integer aNbPBP;
274   //
275   myErrorStatus=0;
276   //
277   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
278   aNbPBP=aPBP.Extent();
279   if(!aNbPBP) {
280     return;
281   }
282   //
283   Standard_Boolean bV1, bV2;
284   Standard_Integer i, nV1, nV2, aNbPB;
285   Handle(BOPDS_PaveBlock) aPB;
286   //
287   for (i=0; i<aNbPBP; ++i) {
288     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
289     //
290     aNbPB=aLPB.Extent();
291     if (aNbPB==1) {
292       aPB=aLPB.First();
293       aPB->Indices(nV1, nV2);
294       bV1=myDS->IsNewShape(nV1);
295       bV2=myDS->IsNewShape(nV2);
296       //
297       if (!(bV1 || bV2)) {
298         if (!myDS->IsCommonBlock(aPB)) {
299           // the PB seems to be untouced
300           aLPB.Clear();
301           continue;
302         }
303       }//if (!(bV1 || bV2)) {
304     }//if (aNbPB==1) {
305   }//for (i=0; i<aNbPBP; ++i) {
306   myDS->RefineFaceInfoOn();
307 }
308
309 //=======================================================================
310 //function : UpdateVertices
311 //purpose  : update tolerances of vertices comparing extremities of
312 //           3d and 2d curves
313 //=======================================================================
314 void UpdateVertices(const TopoDS_Edge& aE, const TopoDS_Face& aF)
315 {
316   Standard_Integer j;
317   Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
318   gp_Pnt aP3D, aP3Dx;
319   gp_Pnt2d aP2Dx;
320   Handle(Geom_Surface) aS;
321   Handle(Geom_Curve) aC3D;
322   Handle(Geom2d_Curve) aC2D;
323   TopoDS_Edge aEf;
324   TopoDS_Vertex aV[2];
325   BRep_Builder aBB;
326   //
327   aEf=aE;
328   aEf.Orientation(TopAbs_FORWARD);
329   //
330   TopExp::Vertices(aEf, aV[0], aV[1]);
331   //
332   aS=BRep_Tool::Surface(aF);
333   aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
334   aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
335   //
336   for (j=0; j<2; ++j) {
337     aTolV2=BRep_Tool::Tolerance(aV[j]);
338     aTolV2=aTolV2*aTolV2;
339     //
340     aC3D->D0(aT[j], aP3D);
341     aC2D->D0(aT[j], aP2Dx);
342     aP2Dx.Coord(aUx, aVx);
343     aS->D0(aUx, aVx, aP3Dx);
344     aD2=aP3D.SquareDistance(aP3Dx);
345     if (aD2>aTolV2) {
346       aD=sqrt(aD2);
347       aBB.UpdateVertex(aV[j], aD);
348     }
349   }
350 }
351