0026619: Tolerances of operands are modified using bop
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_8.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 #include <BOPAlgo_SectionAttribute.hxx>
20 #include <BOPCol_ListOfInteger.hxx>
21 #include <BOPDS_Curve.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_FaceInfo.hxx>
24 #include <BOPDS_MapOfPaveBlock.hxx>
25 #include <BOPDS_Pave.hxx>
26 #include <BOPDS_PaveBlock.hxx>
27 #include <BOPDS_ShapeInfo.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <ElCLib.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <Geom2dAdaptor_Curve.hxx>
35 #include <Geom2dInt_GInter.hxx>
36 #include <gp_Lin2d.hxx>
37 #include <gp_Pnt.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <IntRes2d_IntersectionPoint.hxx>
40 #include <IntTools_Context.hxx>
41 #include <Precision.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Vertex.hxx>
45
46 static
47   void MakeSplitEdge1 (const TopoDS_Edge&   aE,
48                        const TopoDS_Face&   aF,
49                        const TopoDS_Vertex& aV1,
50                        const Standard_Real  aP1,
51                        const TopoDS_Vertex& aV2,
52                        const Standard_Real  aP2,
53                        TopoDS_Edge& aNewEdge);
54
55 //=======================================================================
56 //function : ProcessDE
57 //purpose  : 
58 //=======================================================================
59 void BOPAlgo_PaveFiller::ProcessDE()
60 {
61   Standard_Integer nF, aNb, nE, nV, nVSD, aNbPB;
62   Handle(NCollection_BaseAllocator) aAllocator;
63   Handle(BOPDS_PaveBlock) aPBD;
64   BOPCol_ListIteratorOfListOfInteger aItLI;
65   //
66   myErrorStatus=0;
67   //
68   // 1. Find degnerated edges
69   //-----------------------------------------------------scope f
70   //
71   aAllocator=
72     NCollection_BaseAllocator::CommonBaseAllocator();
73   BOPDS_ListOfPaveBlock aLPBOut(aAllocator);
74   //
75   aNb=myDS->NbSourceShapes();
76   for (nE=0; nE<aNb; ++nE) {
77     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
78     if (aSIE.ShapeType()==TopAbs_EDGE) {
79       if (aSIE.HasFlag(nF)) {
80         const BOPDS_ShapeInfo& aSIF=myDS->ShapeInfo(nF);
81         nV=aSIE.SubShapes().First();
82         if (myDS->HasShapeSD(nV, nVSD)) {
83           nV=nVSD;
84         }
85         //nV,nE,nF
86         //
87         if (aSIF.ShapeType() == TopAbs_FACE) {
88           // 1. Find PaveBlocks that are go through nV for nF
89           FindPaveBlocks(nV, nF, aLPBOut);
90           aNbPB=aLPBOut.Extent();
91           if (aNbPB) {
92             //
93             // 2.
94             BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(nE);
95             aPBD = aLPBD.First();
96             //
97             FillPaves(nV, nE, nF, aLPBOut, aPBD);
98             //
99             myDS->UpdatePaveBlock(aPBD);
100           }
101           //
102           MakeSplitEdge(nE, nF);
103           //
104           aLPBOut.Clear();
105         }
106         if (aSIF.ShapeType() == TopAbs_EDGE) {
107           Standard_Real aTol=1.e-7;
108           Standard_Integer nEn;
109           BRep_Builder BB;
110           const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
111           const TopoDS_Vertex& aVn = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
112           //
113           TopoDS_Edge aE=aDE;
114           aE.EmptyCopy();
115           BB.Add(aE, aVn);
116           BB.Degenerated(aE, Standard_True);
117           BB.UpdateEdge(aE, aTol);
118           BOPDS_ShapeInfo aSI;
119           aSI.SetShapeType(TopAbs_EDGE);
120           aSI.SetShape(aE);
121           nEn=myDS->Append(aSI);
122           BOPDS_ListOfPaveBlock& aLPBD=myDS->ChangePaveBlocks(nE);
123           aPBD=aLPBD.First();
124           aPBD->SetEdge(nEn);
125         }
126       }
127     }
128   }
129 }
130
131 //=======================================================================
132 //function : FindPaveBlocks
133 //purpose  : 
134 //=======================================================================
135   void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer nV,
136                                           const Standard_Integer nF,
137                                           BOPDS_ListOfPaveBlock& aLPBOut)
138 {
139   Standard_Integer i, aNbPBOn, aNbPBIn, aNbPBSc, nV1, nV2;
140   //
141   const BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
142   // In
143   const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
144   aNbPBIn = aMPBIn.Extent();
145   for (i = 1; i <= aNbPBIn; ++i) {
146     const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(i);
147     aPB->Indices(nV1, nV2);
148     if (nV==nV1 || nV==nV2) {
149       aLPBOut.Append(aPB);
150     }
151   }
152   // On
153   const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
154   aNbPBOn = aMPBOn.Extent();
155   for (i = 1; i <= aNbPBOn; ++i) {
156     const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(i);
157     aPB->Indices(nV1, nV2);
158     if (nV==nV1 || nV==nV2) {
159       aLPBOut.Append(aPB);
160     }
161   }
162   // Sections
163   const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
164   aNbPBSc = aMPBSc.Extent();
165   for (i = 1; i <= aNbPBSc; ++i) {
166     const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i);
167     aPB->Indices(nV1, nV2);
168     if (nV==nV1 || nV==nV2) {
169       aLPBOut.Append(aPB);
170     }
171   }
172 }
173
174 //=======================================================================
175 //function : MakeSplitEdge
176 //purpose  : 
177 //=======================================================================
178   void BOPAlgo_PaveFiller::MakeSplitEdge (const Standard_Integer nDE,
179                                           const Standard_Integer nDF)
180
181   Standard_Integer nSp, nV1, nV2, aNbPB;
182   Standard_Real aT1, aT2;
183   TopoDS_Edge aDE, aSp;
184   TopoDS_Vertex aV1, aV2;
185   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
186   BOPDS_ShapeInfo aSI;
187   //
188   aSI.SetShapeType(TopAbs_EDGE);
189   //
190   aDE=(*(TopoDS_Edge *)(&myDS->Shape(nDE))); 
191   aDE.Orientation(TopAbs_FORWARD);
192   //
193   const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nDF)));
194   //
195   BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nDE);
196   aNbPB=aLPB.Extent();
197   //
198   aItLPB.Initialize(aLPB);
199   for (; aItLPB.More(); aItLPB.Next()) {
200     Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
201     //
202     const BOPDS_Pave& aPave1=aPB->Pave1();
203     aPave1.Contents(nV1, aT1);
204     //
205     const BOPDS_Pave& aPave2=aPB->Pave2();
206     aPave2.Contents(nV2, aT2);
207     //
208     if (myDS->IsNewShape(nV1) || aNbPB>1) {
209       aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
210       aV1.Orientation(TopAbs_FORWARD); 
211       //
212       aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
213       aV2.Orientation(TopAbs_REVERSED); 
214       //
215       MakeSplitEdge1(aDE, aDF, aV1, aT1, aV2, aT2, aSp); 
216       //
217       aSI.SetShape(aSp);
218       nSp=myDS->Append(aSI);
219       aPB->SetEdge(nSp);
220     }
221     else {
222       //aPB->SetEdge(nDE);
223       aLPB.Clear();
224       break;
225     }
226   }
227 }
228
229 //=======================================================================
230 //function : FillPaves
231 //purpose  : 
232 //=======================================================================
233   void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD,
234                                      const Standard_Integer nED,
235                                      const Standard_Integer nFD,
236                                      const BOPDS_ListOfPaveBlock& aLPBOut,
237                                      const Handle(BOPDS_PaveBlock)& aPBD)
238 {
239   Standard_Boolean bXDir, bIsDone;
240   Standard_Integer nE, aNbPoints, j, anInd;
241   Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT;
242   Standard_Real aTolCmp;
243   gp_Pnt2d aP2d1, aP2d2, aP2D;
244   gp_Lin2d aLDE;
245   Handle(Geom2d_Line) aCLDE;
246   Handle(Geom2d_Curve) aC2DDE1, aC2D;
247   Handle(Geom2d_TrimmedCurve)aC2DDE;
248   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
249   BOPDS_Pave aPave;
250   //
251   aDT=Precision::PConfusion();
252   //
253   aPave.SetIndex(nVD);
254   //
255   const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nED)));
256   const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nFD)));
257   //aC2DDE
258   aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
259   aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2);
260   //aCLDE
261   Handle(Geom2d_TrimmedCurve) aCLDET1=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1);
262   if (aCLDET1.IsNull()) {
263     aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
264   }
265   else {
266     Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve();
267     aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve);
268   }
269   //
270   // Choose direction for degenerated edge
271   aC2DDE->D0(aTD1, aP2d1);
272   aC2DDE->D0(aTD2, aP2d2);
273   //
274   bXDir=Standard_False;
275   if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
276     bXDir=!bXDir;
277   }
278   //
279   aItLPB.Initialize(aLPBOut);
280   for (; aItLPB.More(); aItLPB.Next()) {
281     const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
282     nE=aPB->Edge();
283     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
284     aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
285     if (aC2D.IsNull()) {
286       continue;
287     }
288     //
289     // Intersection
290     Geom2dAdaptor_Curve aGAC1, aGAC2;
291     aGAC1.Load(aC2DDE, aTD1, aTD2);
292     //
293     Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
294     if (!aL2D.IsNull()) {
295       aGAC2.Load(aC2D);
296     }
297     else {
298       aGAC2.Load(aC2D, aT1, aT2);
299     }
300     //
301     aTolInter=0.001;
302     aTolCmp=1.414213562*aTolInter+aDT;
303     Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
304     bIsDone=aGInter.IsDone();
305     if(!bIsDone) {
306       continue;
307     }
308     //
309     aNbPoints=aGInter.NbPoints();
310     if (!aNbPoints){
311       continue;
312     }
313     //
314     for (j=1; j<=aNbPoints; ++j) {
315       aP2D=aGInter.Point(j).Value();
316       aX=aGInter.Point(j).ParamOnFirst();
317       //
318       if (fabs (aX-aTD1) < aTolCmp || fabs (aX-aTD2) < aTolCmp) {
319         continue; 
320       }
321       if (aX < aTD1 || aX > aTD2) {
322         continue; 
323       }
324       //
325       if (aPBD->ContainsParameter(aX, aDT, anInd)) {
326         continue;
327       }
328       aPave.SetParameter(aX);
329       aPBD->AppendExtPave1(aPave);
330     }
331   }//for (; aItLPB.More(); aItLPB.Next()) {
332 }
333 //=======================================================================
334 // function:  MakeSplitEdge1
335 // purpose: 
336 //=======================================================================
337   void MakeSplitEdge1 (const TopoDS_Edge&   aE,
338                        const TopoDS_Face&   aF,
339                        const TopoDS_Vertex& aV1,
340                        const Standard_Real  aP1,
341                        const TopoDS_Vertex& aV2,
342                        const Standard_Real  aP2,
343                        TopoDS_Edge& aNewEdge)
344 {
345   Standard_Real aTol=1.e-7;
346
347   TopoDS_Edge E=aE;
348
349   E.EmptyCopy();
350   BRep_Builder BB;
351   BB.Add  (E, aV1);
352   BB.Add  (E, aV2);
353
354   BB.Range(E, aF, aP1, aP2);
355
356   BB.Degenerated(E, Standard_True);
357
358   BB.UpdateEdge(E, aTol);
359   aNewEdge=E;
360 }