0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / QANewModTopOpe / QANewModTopOpe_Intersection.cxx
CommitLineData
b311480e 1// Created on: 2000-12-25
2// Created by: Igor FEOKTISTOV
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <QANewModTopOpe_Intersection.ixx>
17#include <TopoDS.hxx>
18#include <TopTools_ListIteratorOfListOfShape.hxx>
19#include <BRep_Builder.hxx>
20#include <BRep_Tool.hxx>
21#include <TopExp_Explorer.hxx>
22#include <BRepExtrema_SupportType.hxx>
23#include <BRepExtrema_DistShapeShape.hxx>
24#include <BRepBuilderAPI_MakeVertex.hxx>
25#include <TopoDS_Vertex.hxx>
26#include <gp_Pnt.hxx>
27#include <BRepAlgo_EdgeConnector.hxx>
28#include <TopTools_ListOfShape.hxx>
29#include <TopoDS_Iterator.hxx>
30#include <BRepTools.hxx>
7fd59977 31#include <TopTools_MapOfShape.hxx>
32#include <TopoDS_Edge.hxx>
33#include <QANewModTopOpe_Tools.hxx>
34
4e57c75e 35#include <BOPAlgo_PaveFiller.hxx>
36
7fd59977 37
38static Standard_Boolean NoFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2)
39{
40 TopExp_Explorer Ex;
41 Ex.Init(S1,TopAbs_FACE);
42 Standard_Boolean f1 = Ex.More();
43 Ex.Init(S2,TopAbs_FACE);
44 Standard_Boolean f2 = Ex.More();
45
46 return !f1&&!f2;
47}
48
49QANewModTopOpe_Intersection::QANewModTopOpe_Intersection( const TopoDS_Shape& theObject1,
50 const TopoDS_Shape& theObject2 )
4e57c75e 51: BRepAlgoAPI_BooleanOperation( theObject1, theObject2, BOPAlgo_SECTION)
7fd59977 52{
53 myMapGener.Clear();
54
55 if(NoFaces(myS1, myS2)) {
56
57 BRep_Builder BB;
58 BB.MakeCompound(TopoDS::Compound(myShape));
59
60 BRepExtrema_DistShapeShape DSS(myS1, myS2);
61
62
63 if(DSS.IsDone() && DSS.NbSolution() > 0) {
64 Standard_Integer nbs = DSS.NbSolution();
65 Standard_Real mindist = DSS.Value();
66 Standard_Real maxtol = 0., tol;
67 TopExp_Explorer ExV;
68 for(ExV.Init(myS1,TopAbs_VERTEX); ExV.More(); ExV.Next()) {
69 TopoDS_Vertex Vertex=TopoDS::Vertex(ExV.Current());
70 tol=BRep_Tool::Tolerance(Vertex);
71 if(tol > maxtol) maxtol = tol;
72 }
73
74 for(ExV.Init(myS2,TopAbs_VERTEX); ExV.More(); ExV.Next()) {
75 TopoDS_Vertex Vertex=TopoDS::Vertex(ExV.Current());
76 tol=BRep_Tool::Tolerance(Vertex);
77 if(tol > maxtol) maxtol = tol;
78 }
79
80 if(mindist <= maxtol) {
81 tol = maxtol*maxtol;
82 Standard_Integer i;
83
84 for(i = 1; i <= nbs; i++) {
85 gp_Pnt p1 = DSS.PointOnShape1(i);
86 gp_Pnt p2 = DSS.PointOnShape2(i);
87 if(p1.SquareDistance(p2) > tol) continue;
88 BRepExtrema_SupportType aSupTyp = DSS. SupportTypeShape1(i);
89 if(aSupTyp == BRepExtrema_IsVertex) {
90 BB.Add(myShape, DSS.SupportOnShape1(i));
91 }
92 else {
93 aSupTyp = DSS. SupportTypeShape2(i);
94 if(aSupTyp == BRepExtrema_IsVertex) {
95 BB.Add(myShape, DSS.SupportOnShape2(i));
96 }
97 else {
98 gp_Pnt p(.5*(p1.XYZ()+p2.XYZ()));
99 BRepBuilderAPI_MakeVertex mkV(p);
100 BB.Add(myShape, mkV.Vertex());
101
102 if (!myMapGener.IsBound(DSS. SupportOnShape1(i))) {
103 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(DSS.SupportOnShape1(i), TopTools_ListOfShape());
104 TopTools_ListOfShape aListOfShape1;
105 myMapGener.Bind(DSS.SupportOnShape1(i), aListOfShape1);
106 }
107 myMapGener(DSS.SupportOnShape1(i)).Append(mkV.Vertex());
108
109 if (!myMapGener.IsBound(DSS.SupportOnShape2(i))) {
110 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(DSS.SupportOnShape2(i), TopTools_ListOfShape());
111 TopTools_ListOfShape aListOfShape2;
112 myMapGener.Bind(DSS.SupportOnShape2(i), aListOfShape2);
113 }
114 myMapGener(DSS.SupportOnShape2(i)).Append(mkV.Vertex());
115
116 }
117
118 }
119 }
120 }
121 }
122
123 Done();
124 return;
125 }
126
127 Standard_Boolean bIsNewFiller = PrepareFiller();
128 //
129 if (myErrorStatus!=1) {
130 // there were errors during the preparation
131 return;
132 }
133 //
134 if (bIsNewFiller) {
135 //Prepare the DS
4e57c75e 136 myDSFiller->Perform();
137
7fd59977 138 }
139
140 Build();
141
142 Standard_Boolean bcw = BuilderCanWork();
143
144 if ( ! bcw ) return;
145
146 BRep_Builder BB;
147 BB.MakeCompound(TopoDS::Compound(myShape));
148 TopTools_ListIteratorOfListOfShape itloe(SectionEdges());
149
150 if(itloe.More()) {
151
152 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
153
154 // try to make wire from set of edges
155 TopTools_ListOfShape LOEdge;
156 TopTools_ListOfShape LOSEdge;
157 Standard_Integer nbe = 0;
158 TopoDS_Shape aux;
159 TopExp_Explorer Ex;
160 BB.MakeCompound(TopoDS::Compound(aux));
161 for(Ex.Init(myShape,TopAbs_EDGE); Ex.More(); Ex.Next()) {
162 LOEdge.Append(Ex.Current());
163 LOSEdge.Append(Ex.Current());
164 nbe++;
165 }
166 BRepAlgo_EdgeConnector EC;
167 TopoDS_Shape se = LOEdge.First();
168 EC.Add(LOEdge);
169 EC.AddStart(LOSEdge);
170 const TopTools_ListOfShape& LOWire = EC.MakeBlock();
171 TopTools_ListIteratorOfListOfShape its;
172 for(its.Initialize(LOWire);its.More();its.Next()) {
173 BB.Add(aux,its.Value());
174 }
175 for(Ex.Init(aux,TopAbs_EDGE); Ex.More(); Ex.Next()) {
176 nbe--;
177 }
178 if(nbe == 0) myShape = aux;
179
180 }
181 else {
182 // check if there are new vertices - IFV
183
184 Standard_Integer nbp = QANewModTopOpe_Tools::NbPoints(myDSFiller);
185
186 if(nbp > 0) {
187
188 TopoDS_Shape aux1, aux2;
189 BB.MakeCompound(TopoDS::Compound(aux1));
190 BB.MakeCompound(TopoDS::Compound(aux2));
191
192 BB.Add(aux1, myS1);
193 BB.Add(aux1, myS2);
194
195 Standard_Integer i;
196 Standard_Real maxtol = 0., tol;
197
198 for(i = 1; i <= nbp; i++) {
199 TopoDS_Vertex aVertex=
200 TopoDS::Vertex(QANewModTopOpe_Tools::NewVertex(myDSFiller, i));
201
202 tol=BRep_Tool::Tolerance(aVertex);
203 if(tol > maxtol) maxtol = tol;
204 BB.Add(aux2, aVertex);
205 }
206
207 BRepExtrema_DistShapeShape DSS(aux1, aux2);
208 if(DSS.IsDone() && DSS.NbSolution() > 0) {
209 Standard_Integer nbs = DSS.NbSolution();
210 Standard_Real mindist = DSS.Value();
211 if(mindist <= maxtol) {
212 tol = maxtol*maxtol;
213
214 TopTools_MapOfShape aMap;
215
216 for(i = 1; i <= nbs; i++) {
217 gp_Pnt p1 = DSS.PointOnShape1(i);
218 gp_Pnt p2 = DSS.PointOnShape2(i);
219 if(p1.SquareDistance(p2) > tol) continue;
220 BRepExtrema_SupportType aSupTyp = DSS.SupportTypeShape1(i);
221 TopoDS_Vertex aVertex;
222 if(aSupTyp == BRepExtrema_IsVertex) {
223 aVertex = TopoDS::Vertex(DSS.SupportOnShape1(i));
224 TopoDS_Iterator anIter(myShape);
225 Standard_Boolean anIsNew = Standard_True;
226 for(; anIter.More(); anIter.Next()) {
227 if(BRepTools::Compare(aVertex, TopoDS::Vertex(anIter.Value()))) {
228 anIsNew = Standard_False;
229 break;
230 }
231 }
232 if(anIsNew) {
233 BB.Add(myShape, aVertex);
234 }
235 }
236 else {
237 aVertex = TopoDS::Vertex(DSS.SupportOnShape2(i));
238 if(aMap.Add(aVertex)) BB.Add(myShape, aVertex);
239 if (!myMapGener.IsBound(DSS.SupportOnShape1(i))) {
240 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(DSS.SupportOnShape1(i), TopTools_ListOfShape());
241 TopTools_ListOfShape aListOfShape3;
242 myMapGener.Bind(DSS.SupportOnShape1(i), aListOfShape3);
243 }
244 myMapGener(DSS.SupportOnShape1(i)).Append(aVertex);
245
246 }
247 } // end for
248 }
249 }
250 }
251 }
252
253
254 Done();
255
256}
257
258//=======================================================================
259//function : Generated
260//purpose : gives list of shape generated from shape S
261//=======================================================================
262const TopTools_ListOfShape& QANewModTopOpe_Intersection::Generated(const TopoDS_Shape& theS)
263{
264 myGenerated.Clear();
265
266 if(theS.ShapeType() == TopAbs_FACE || theS.ShapeType() == TopAbs_EDGE) {
267 if (BRepAlgoAPI_BooleanOperation::HasGenerated()) {
268 const TopTools_ListOfShape &aLOfShape =
269 BRepAlgoAPI_BooleanOperation::Generated(theS);
270 TopTools_ListIteratorOfListOfShape anIter(aLOfShape);
271
272 for (; anIter.More(); anIter.Next()) {
273 const TopoDS_Shape &aGenShape = anIter.Value();
274
275 if (aGenShape.ShapeType() == TopAbs_VERTEX)
276 continue;
277
278 myGenerated.Append(aGenShape);
279 }
280 }
281
282 if(myMapGener.IsBound(theS)) {
283 TopTools_ListIteratorOfListOfShape anIter(myMapGener(theS));
284
285 for(; anIter.More(); anIter.Next())
286 myGenerated.Append(anIter.Value());
287 }
288 }
289
290 return myGenerated;
291
292}
293
294//=======================================================================
295//function : HasGenerated
296//purpose :
297//=======================================================================
298Standard_Boolean QANewModTopOpe_Intersection::HasGenerated() const
299{
300 Standard_Boolean aHasGenerated = Standard_False;
301
302 if (BRepAlgoAPI_BooleanOperation::HasGenerated()) {
303 aHasGenerated = Standard_True;
304 }
305 else {
306 aHasGenerated = !myMapGener.IsEmpty();
307 }
308 return aHasGenerated;
309}
310
311
312//=======================================================================
313//function : IsDeleted
314//purpose :
315//=======================================================================
316Standard_Boolean QANewModTopOpe_Intersection::IsDeleted(const TopoDS_Shape& aS)
317{
318 if(BRepAlgoAPI_BooleanOperation::IsDeleted(aS))
319 return Standard_True;
320
321 if(myMapGener.IsBound(aS))
322 return Standard_False;
323 return Standard_True;
324}
325
326//=======================================================================
327//function : HasDeleted
328//purpose :
329//=======================================================================
330Standard_Boolean QANewModTopOpe_Intersection::HasDeleted() const
331{
7fd59977 332 TopExp_Explorer anExp;
333
334 for(Standard_Integer argit = 0; argit < 2; argit++) {
335 Standard_Boolean bTillVertex = Standard_True;
336
337 if(argit == 0)
338 anExp.Init(myS1, TopAbs_FACE);
339 else
340 anExp.Init(myS2, TopAbs_FACE);
341
342 if(anExp.More())
343 bTillVertex = Standard_False;
344 Standard_Integer nb = (bTillVertex) ? 3 : 2;
345
346 for(Standard_Integer i = 0; i < nb; i++) {
347 TopAbs_ShapeEnum aType = (i == 0) ? TopAbs_FACE : ((i == 1) ? TopAbs_EDGE : TopAbs_VERTEX);
348
349 if(argit == 0)
350 anExp.Init(myS1, aType);
351 else
352 anExp.Init(myS2, aType);
353
354 for(; anExp.More(); anExp.Next()) {
355 if(!myMapGener.IsBound(anExp.Current())) {
356 return Standard_True;
357 }
358 }
359 }
360 }
361 return Standard_False;
362}