0030092: Modeling Algorithms - Invalid result of Section operation
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller.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 <BOPAlgo_Alerts.hxx>
22 #include <BOPDS_Curve.hxx>
23 #include <BOPDS_DS.hxx>
24 #include <BOPDS_Iterator.hxx>
25 #include <BOPDS_PaveBlock.hxx>
26 #include <gp_Pnt.hxx>
27 #include <IntTools_Context.hxx>
28 #include <NCollection_BaseAllocator.hxx>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_Failure.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopTools_ListIteratorOfListOfShape.hxx>
34
35 //=======================================================================
36 //function : 
37 //purpose  : 
38 //=======================================================================
39 BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
40 :
41   BOPAlgo_Algo()
42 {
43   myDS = NULL;
44   myIterator = NULL;
45   myNonDestructive = Standard_False;
46   myIsPrimary = Standard_True;
47   myAvoidBuildPCurve = Standard_False;
48   myGlue = BOPAlgo_GlueOff;
49 }
50 //=======================================================================
51 //function : 
52 //purpose  : 
53 //=======================================================================
54 BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
55   (const Handle(NCollection_BaseAllocator)& theAllocator)
56 :
57   BOPAlgo_Algo(theAllocator),
58   myFPBDone(1, theAllocator),
59   myIncreasedSS(1, theAllocator),
60   myVertsToAvoidExtension(1, theAllocator)
61 {
62   myDS = NULL;
63   myIterator = NULL;
64   myNonDestructive = Standard_False;
65   myIsPrimary = Standard_True;
66   myAvoidBuildPCurve = Standard_False;
67   myGlue = BOPAlgo_GlueOff;
68 }
69 //=======================================================================
70 //function : ~
71 //purpose  : 
72 //=======================================================================
73 BOPAlgo_PaveFiller::~BOPAlgo_PaveFiller()
74 {
75   Clear();
76 }
77 //=======================================================================
78 //function : SetNonDestructive
79 //purpose  : 
80 //=======================================================================
81 void BOPAlgo_PaveFiller::SetNonDestructive(const Standard_Boolean bFlag)
82 {
83   myNonDestructive=bFlag;
84 }
85 //=======================================================================
86 //function : NonDestructive
87 //purpose  : 
88 //=======================================================================
89 Standard_Boolean BOPAlgo_PaveFiller::NonDestructive()const 
90 {
91   return myNonDestructive;
92 }
93 //=======================================================================
94 //function : SetGlue
95 //purpose  : 
96 //=======================================================================
97 void BOPAlgo_PaveFiller::SetGlue(const BOPAlgo_GlueEnum theGlue)
98 {
99   myGlue=theGlue;
100 }
101 //=======================================================================
102 //function : Glue
103 //purpose  : 
104 //=======================================================================
105 BOPAlgo_GlueEnum BOPAlgo_PaveFiller::Glue() const 
106 {
107   return myGlue;
108 }
109 //=======================================================================
110 //function : SetIsPrimary
111 //purpose  : 
112 //=======================================================================
113 void BOPAlgo_PaveFiller::SetIsPrimary(const Standard_Boolean bFlag)
114 {
115   myIsPrimary=bFlag;
116 }
117 //=======================================================================
118 //function : IsPrimary
119 //purpose  : 
120 //=======================================================================
121 Standard_Boolean BOPAlgo_PaveFiller::IsPrimary()const 
122 {
123   return myIsPrimary;
124 }
125 //=======================================================================
126 //function : Clear
127 //purpose  : 
128 //=======================================================================
129 void BOPAlgo_PaveFiller::Clear()
130 {
131   BOPAlgo_Algo::Clear();
132   if (myIterator) {
133     delete myIterator;
134     myIterator=NULL;
135   }
136   if (myDS) {
137     delete myDS;
138     myDS=NULL;
139   }
140   myIncreasedSS.Clear();
141 }
142 //=======================================================================
143 //function : DS
144 //purpose  : 
145 //=======================================================================
146 const BOPDS_DS& BOPAlgo_PaveFiller::DS()
147 {
148   return *myDS;
149 }
150 //=======================================================================
151 //function : PDS
152 //purpose  : 
153 //=======================================================================
154 BOPDS_PDS BOPAlgo_PaveFiller::PDS()
155 {
156   return myDS;
157 }
158 //=======================================================================
159 //function : Context
160 //purpose  : 
161 //=======================================================================
162 const Handle(IntTools_Context)& BOPAlgo_PaveFiller::Context()
163 {
164   return myContext;
165 }
166 //=======================================================================
167 //function : SectionAttribute
168 //purpose  : 
169 //=======================================================================
170 void BOPAlgo_PaveFiller::SetSectionAttribute
171   (const BOPAlgo_SectionAttribute& theSecAttr)
172 {
173   mySectionAttribute = theSecAttr;
174 }
175 //=======================================================================
176 //function : SetArguments
177 //purpose  : 
178 //=======================================================================
179 void BOPAlgo_PaveFiller::SetArguments(const TopTools_ListOfShape& theLS)
180 {
181   myArguments=theLS;
182 }
183 //=======================================================================
184 //function : Arguments
185 //purpose  : 
186 //=======================================================================
187 const TopTools_ListOfShape& BOPAlgo_PaveFiller::Arguments()const
188 {
189   return myArguments;
190 }
191 //=======================================================================
192 // function: Init
193 // purpose: 
194 //=======================================================================
195 void BOPAlgo_PaveFiller::Init()
196 {
197   if (!myArguments.Extent()) {
198     AddError (new BOPAlgo_AlertTooFewArguments);
199     return;
200   }
201   //
202   TopTools_ListIteratorOfListOfShape aIt(myArguments);
203   for (; aIt.More(); aIt.Next()) {
204     if (aIt.Value().IsNull()) {
205       AddError (new BOPAlgo_AlertNullInputShapes);
206       return;
207     }
208   }
209   //
210   // 0 Clear
211   Clear();
212   //
213   // 1.myDS 
214   myDS=new BOPDS_DS(myAllocator);
215   myDS->SetArguments(myArguments);
216   myDS->Init(myFuzzyValue);
217   //
218   // 2 myContext
219   myContext=new IntTools_Context;
220   //
221   // 3.myIterator 
222   myIterator=new BOPDS_Iterator(myAllocator);
223   myIterator->SetRunParallel(myRunParallel);
224   myIterator->SetDS(myDS);
225   myIterator->Prepare(myContext, myUseOBB, myFuzzyValue);
226   //
227   // 4 NonDestructive flag
228   SetNonDestructive();
229 }
230 //=======================================================================
231 // function: Perform
232 // purpose: 
233 //=======================================================================
234 void BOPAlgo_PaveFiller::Perform()
235 {
236   try {
237     OCC_CATCH_SIGNALS
238     //
239     PerformInternal();
240   }
241   //
242   catch (Standard_Failure) {
243     AddError (new BOPAlgo_AlertIntersectionFailed);
244   } 
245 }
246 //=======================================================================
247 // function: PerformInternal
248 // purpose: 
249 //=======================================================================
250 void BOPAlgo_PaveFiller::PerformInternal()
251 {
252   Init();
253   if (HasErrors()) {
254     return; 
255   }
256   //
257   Prepare();
258   if (HasErrors()) {
259     return; 
260   }
261   // 00
262   PerformVV();
263   if (HasErrors()) {
264     return; 
265   }
266   // 01
267   PerformVE();
268   if (HasErrors()) {
269     return; 
270   }
271   //
272   UpdatePaveBlocksWithSDVertices();
273   // 11
274   PerformEE();
275   if (HasErrors()) {
276     return; 
277   }
278   UpdatePaveBlocksWithSDVertices();
279   // 02
280   PerformVF();
281   if (HasErrors()) {
282     return; 
283   }
284   UpdatePaveBlocksWithSDVertices();
285   // 12
286   PerformEF();
287   if (HasErrors()) {
288     return; 
289   }
290   UpdatePaveBlocksWithSDVertices();
291   UpdateInterfsWithSDVertices();
292
293   // Repeat Intersection with increased vertices
294   RepeatIntersection();
295   if (HasErrors())
296     return;
297
298   // Force intersection of edges after increase
299   // of the tolerance values of their vertices
300   ForceInterfEE();
301   // Force Edge/Face intersection after increase
302   // of the tolerance values of their vertices
303   ForceInterfEF();
304   //
305   // 22
306   PerformFF();
307   if (HasErrors()) {
308     return; 
309   }
310   //
311   UpdateBlocksWithSharedVertices();
312   //
313   MakeSplitEdges();
314   if (HasErrors()) {
315     return; 
316   }
317   //
318   UpdatePaveBlocksWithSDVertices();
319   //
320   MakeBlocks();
321   if (HasErrors()) {
322     return; 
323   }
324   //
325   CheckSelfInterference();
326   //
327   UpdateInterfsWithSDVertices();
328   myDS->ReleasePaveBlocks();
329   myDS->RefineFaceInfoOn();
330   //
331   RemoveMicroEdges();
332   //
333   MakePCurves();
334   if (HasErrors()) {
335     return; 
336   }
337   //
338   ProcessDE();
339   if (HasErrors()) {
340     return; 
341   }
342 }
343
344 //=======================================================================
345 // function: RepeatIntersection
346 // purpose: 
347 //=======================================================================
348 void BOPAlgo_PaveFiller::RepeatIntersection()
349 {
350   // Find all vertices with increased tolerance
351   TColStd_MapOfInteger anExtraInterfMap;
352   const Standard_Integer aNbS = myDS->NbSourceShapes();
353   for (Standard_Integer i = 0; i < aNbS; ++i)
354   {
355     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
356     if (aSI.ShapeType() != TopAbs_VERTEX)
357       continue;
358     // Check if the tolerance of the original vertex has been increased
359     if (myIncreasedSS.Contains(i))
360     {
361       anExtraInterfMap.Add(i);
362       continue;
363     }
364
365     // Check if the vertex created a new vertex with greater tolerance
366     Standard_Integer nVSD;
367     if (!myDS->HasShapeSD(i, nVSD))
368       continue;
369
370     if (myIncreasedSS.Contains(nVSD))
371       anExtraInterfMap.Add(i);
372   }
373
374   if (anExtraInterfMap.IsEmpty())
375     return;
376
377   // Update iterator of pairs of shapes with interfering boxes
378   myIterator->PrepareExt(anExtraInterfMap);
379
380   // Perform intersections with vertices
381   PerformVV();
382   if (HasErrors())
383     return;
384   UpdatePaveBlocksWithSDVertices();
385
386   PerformVE();
387   if (HasErrors())
388     return;
389   UpdatePaveBlocksWithSDVertices();
390
391   PerformVF();
392   if (HasErrors())
393     return;
394
395   UpdatePaveBlocksWithSDVertices();
396   UpdateInterfsWithSDVertices();
397 }