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