0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOP / BOP_Section.cxx
1 // Created on: 2001-05-18
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21
22 #include <BOP_Section.ixx>
23
24 #include <BooleanOperations_ShapesDataStructure.hxx>
25
26 #include <TopTools_IndexedMapOfShape.hxx>
27
28 #include <TopoDS_Shape.hxx>
29 #include <TopoDS_Compound.hxx>
30
31 #include <BRep_Builder.hxx>
32
33 #include <BOPTools_SSInterference.hxx>
34 #include <BOPTools_ListOfPaveBlock.hxx>
35 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
36 #include <BOPTools_PaveBlock.hxx>
37 #include <BOPTools_SequenceOfCurves.hxx>
38 #include <BOPTools_Curve.hxx>
39 #include <BOPTools_InterferencePool.hxx>
40 #include <BOPTools_CArray1OfSSInterference.hxx>
41 #include <BOPTools_PaveFiller.hxx>
42 #include <BOPTools_SSIntersectionAttribute.hxx>
43 #include <BOPTools_Tools2D.hxx>
44 #include <BRep_Tool.hxx>
45 #include <Geom_Curve.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS.hxx>
50
51 #include <BOP_CorrectTolerances.hxx>
52
53 #include <BOPTColStd_Dump.hxx>
54
55 #include <BOP_SectionHistoryCollector.hxx>
56
57 #include <Standard_Failure.hxx>
58 #include <Standard_ErrorHandler.hxx>
59
60 //=======================================================================
61 // function: BOP_Section::BOP_Section
62 // purpose: 
63 //=======================================================================
64 BOP_Section::BOP_Section() 
65 {
66   SetOperation (BOP_SECTION);
67 }
68 //=======================================================================
69 // function: Destroy
70 // purpose: 
71 //=======================================================================
72   void BOP_Section::Destroy() {}
73
74 //=======================================================================
75 // function: Do
76 // purpose: 
77 //=======================================================================
78   void BOP_Section::Do()
79 {
80   myErrorStatus=0;
81   myIsDone=Standard_False;
82
83   TopAbs_ShapeEnum aT1, aT2;
84
85   aT1=myShape1.ShapeType();
86   aT2=myShape2.ShapeType();
87
88   BOP_Builder::SortTypes (aT1, aT2);
89   //
90   // Filling the DS
91   BOPTools_DSFiller aDSFiller;
92   aDSFiller.SetShapes (myShape1, myShape2);
93   aDSFiller.Perform (); 
94   DoWithFiller(aDSFiller);
95 }
96
97 //
98 //=======================================================================
99 // function: Do
100 // purpose: 
101 //=======================================================================
102   void BOP_Section::Do(const Standard_Boolean toApprox,
103                        const Standard_Boolean toComputePCurve1,
104                        const Standard_Boolean toComputePCurve2) 
105 {
106   myErrorStatus=0;
107   myIsDone=Standard_False;
108
109   TopAbs_ShapeEnum aT1, aT2;
110
111   aT1=myShape1.ShapeType();
112   aT2=myShape2.ShapeType();
113
114   BOP_Builder::SortTypes (aT1, aT2);
115   //
116   // Filling the DS
117   BOPTools_DSFiller aDSFiller;
118   aDSFiller.SetShapes (myShape1, myShape2);
119
120   BOPTools_SSIntersectionAttribute aSectionAttribute(toApprox, 
121                                                      toComputePCurve1, 
122                                                      toComputePCurve2);
123   aDSFiller.Perform (aSectionAttribute); 
124   DoWithFiller(aDSFiller);
125 }
126 //
127
128 //=======================================================================
129 // function: DoDoWithFiller
130 // purpose: 
131 //=======================================================================
132   void BOP_Section::DoWithFiller(const BOPTools_DSFiller& aDSFiller) 
133 {
134   myErrorStatus=0;
135   myIsDone=Standard_False;
136
137   //
138   myResultMap.Clear();
139   myModifiedMap.Clear();
140   myDSFiller=(BOPTools_DSFiller*) &aDSFiller;
141   //
142
143   try {
144     OCC_CATCH_SIGNALS
145     Standard_Boolean addPCurve1 = aDSFiller.PaveFiller().SectionAttribute().PCurveOnS1();
146     Standard_Boolean addPCurve2 = aDSFiller.PaveFiller().SectionAttribute().PCurveOnS2();
147   
148     Standard_Integer i, j, nF1, nF2,  aNbFFs, aNbS, aNbCurves, nSect;
149     
150     const BooleanOperations_ShapesDataStructure& aDS=aDSFiller.DS();
151     const BOPTools_InterferencePool& anInterfPool=aDSFiller.InterfPool();
152     BOPTools_InterferencePool* pInterfPool= 
153       (BOPTools_InterferencePool*) &anInterfPool;
154     BOPTools_CArray1OfSSInterference& aFFs=
155       pInterfPool->SSInterferences();
156     //
157     TopTools_IndexedMapOfShape aMap;
158     //
159     aNbFFs=aFFs.Extent();
160     for (i=1; i<=aNbFFs; ++i) {
161       BOPTools_SSInterference& aFFi=aFFs(i);
162       //
163       nF1=aFFi.Index1();
164       nF2=aFFi.Index2();
165       
166       TopoDS_Face aF1FWD = TopoDS::Face(aDSFiller.DS().Shape(nF1));
167       aF1FWD.Orientation(TopAbs_FORWARD);
168       TopoDS_Face aF2FWD = TopoDS::Face(aDSFiller.DS().Shape(nF2));
169       aF2FWD.Orientation(TopAbs_FORWARD);
170       //
171       // Old Section Edges
172       const BOPTools_ListOfPaveBlock& aSectList=aFFi.PaveBlocks();
173       aNbS=aSectList.Extent();
174       BOPTools_ListIteratorOfListOfPaveBlock anIt(aSectList);
175       for (; anIt.More();anIt.Next()) {
176         const BOPTools_PaveBlock& aPB=anIt.Value();
177         nSect=aPB.Edge();
178         const TopoDS_Shape& aS=aDS.GetShape(nSect);
179         
180         const TopoDS_Edge& aE = TopoDS::Edge(aS);
181         
182         if(addPCurve1) {
183           BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aF1FWD);
184           }
185         
186         if(addPCurve2) {
187           BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aF2FWD);
188           }
189         aMap.Add(aS);
190       }
191       //
192       // New Section Edges
193       BOPTools_SequenceOfCurves& aBCurves=aFFi.Curves();
194       aNbCurves=aBCurves.Length();
195       for (j=1; j<=aNbCurves; j++) {
196         BOPTools_Curve& aBC=aBCurves(j);
197         const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
198         aNbS=aSectEdges.Extent();
199         
200         BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
201         for (; aPBIt.More(); aPBIt.Next()) {
202           BOPTools_PaveBlock& aPB=aPBIt.Value();
203           nSect=aPB.Edge();
204           const TopoDS_Shape& aS=aDS.GetShape(nSect);
205           
206           if(addPCurve1 || addPCurve2) {
207             const IntTools_Curve& aIC = aBC.Curve();
208             const TopoDS_Edge& aE = TopoDS::Edge(aS);
209             Standard_Real f, l;
210             const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(aE, f, l);
211             Handle(Geom_TrimmedCurve) aC3DETrim;
212             
213             if(!aC3DE.IsNull()) {
214               aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
215             }
216             BRep_Builder aBB;
217             Standard_Real aTolEdge = BRep_Tool::Tolerance(aE);
218             Standard_Real aTolR2D  = aFFi.TolR2D();
219             Standard_Real aTolFact = Max(aTolEdge, aTolR2D);
220             
221             if(addPCurve1 && !BOPTools_Tools2D::HasCurveOnSurface(aE, aF1FWD)) {
222               Handle(Geom2d_Curve) aC2d = aIC.FirstCurve2d();
223               
224               if(!aC3DETrim.IsNull()) {
225                 Handle(Geom2d_Curve) aC2dNew;
226                 
227                 if(aC3DE->IsPeriodic()) {
228                   BOPTools_Tools2D::AdjustPCurveOnFace(aF1FWD, f, l,  aC2d, aC2dNew);
229                   }
230                 else {
231                   BOPTools_Tools2D::AdjustPCurveOnFace(aF1FWD, aC3DETrim, aC2d, aC2dNew); 
232                   }
233                 aC2d = aC2dNew;
234               }
235               aBB.UpdateEdge(aE, aC2d, aF1FWD, aTolFact);
236             }
237             
238             if(addPCurve2 && !BOPTools_Tools2D::HasCurveOnSurface(aE, aF2FWD)) {
239               Handle(Geom2d_Curve) aC2d = aIC.SecondCurve2d();
240               
241               if(!aC3DETrim.IsNull()) {
242                 Handle(Geom2d_Curve) aC2dNew;
243                 
244                 if(aC3DE->IsPeriodic()) {
245                   BOPTools_Tools2D::AdjustPCurveOnFace(aF2FWD, f, l,  aC2d, aC2dNew);
246                   }
247                 else {
248                   BOPTools_Tools2D::AdjustPCurveOnFace(aF2FWD, aC3DETrim, aC2d, aC2dNew); 
249                   }
250                 aC2d = aC2dNew;
251               }
252               aBB.UpdateEdge(aE, aC2d, aF2FWD, aTolFact);
253             }
254           }
255           aMap.Add(aS);
256         }
257       }
258     }
259     //
260     BRep_Builder BB;
261     TopoDS_Compound aCompound;
262     BB.MakeCompound(aCompound);
263     
264     aNbS=aMap.Extent();
265     
266     for (i=1; i<=aNbS; i++) {
267       const TopoDS_Shape& aS=aMap(i);
268       BB.Add(aCompound, aS);
269       mySectionEdges.Append(aS);
270     }
271     myResult=aCompound;
272     BOP_CorrectTolerances::CorrectTolerances(myResult, 0.01);
273     //
274     if (!myErrorStatus) {
275       FillModified();
276
277       if(!myHistory.IsNull()) {
278         Handle(BOP_SectionHistoryCollector) aHistory = 
279           Handle(BOP_SectionHistoryCollector)::DownCast(myHistory);
280         aHistory->SetResult(myResult, myDSFiller);
281       }
282       myIsDone=Standard_True;
283     }
284   }
285   catch ( Standard_Failure ) {
286     myErrorStatus = 1;
287     BOPTColStd_Dump::PrintMessage("Can not build result\n");
288   }
289 }
290
291 //=======================================================================
292 // function: SetHistoryCollector
293 // purpose: 
294 //=======================================================================
295 void BOP_Section::SetHistoryCollector(const Handle(BOP_HistoryCollector)& theHistory) 
296 {
297   if(theHistory.IsNull() ||
298      !theHistory->IsKind(STANDARD_TYPE(BOP_SectionHistoryCollector)))
299     myHistory.Nullify();
300   else
301     myHistory = theHistory;
302 }