0025614: Provide API access to the new fuctionalities of Boolean Components
[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
49b0c452 49//=======================================================================
50//function : QANewModTopOpe_Intersection
51//purpose :
52//=======================================================================
53QANewModTopOpe_Intersection::QANewModTopOpe_Intersection
54 ( const TopoDS_Shape& theObject1,
55 const TopoDS_Shape& theObject2 )
56:
57 BRepAlgoAPI_BooleanOperation( theObject1, theObject2, BOPAlgo_SECTION)
7fd59977 58{
49b0c452 59 TopoDS_Shape& myS1=myArguments.First();
60 TopoDS_Shape& myS2=myTools.First();
61
7fd59977 62 myMapGener.Clear();
63
64 if(NoFaces(myS1, myS2)) {
65
66 BRep_Builder BB;
67 BB.MakeCompound(TopoDS::Compound(myShape));
68
69 BRepExtrema_DistShapeShape DSS(myS1, myS2);
70
71
72 if(DSS.IsDone() && DSS.NbSolution() > 0) {
73 Standard_Integer nbs = DSS.NbSolution();
74 Standard_Real mindist = DSS.Value();
75 Standard_Real maxtol = 0., tol;
76 TopExp_Explorer ExV;
77 for(ExV.Init(myS1,TopAbs_VERTEX); ExV.More(); ExV.Next()) {
78 TopoDS_Vertex Vertex=TopoDS::Vertex(ExV.Current());
79 tol=BRep_Tool::Tolerance(Vertex);
80 if(tol > maxtol) maxtol = tol;
81 }
82
83 for(ExV.Init(myS2,TopAbs_VERTEX); ExV.More(); ExV.Next()) {
84 TopoDS_Vertex Vertex=TopoDS::Vertex(ExV.Current());
85 tol=BRep_Tool::Tolerance(Vertex);
86 if(tol > maxtol) maxtol = tol;
87 }
88
89 if(mindist <= maxtol) {
90 tol = maxtol*maxtol;
91 Standard_Integer i;
92
93 for(i = 1; i <= nbs; i++) {
94 gp_Pnt p1 = DSS.PointOnShape1(i);
95 gp_Pnt p2 = DSS.PointOnShape2(i);
96 if(p1.SquareDistance(p2) > tol) continue;
97 BRepExtrema_SupportType aSupTyp = DSS. SupportTypeShape1(i);
98 if(aSupTyp == BRepExtrema_IsVertex) {
99 BB.Add(myShape, DSS.SupportOnShape1(i));
100 }
101 else {
102 aSupTyp = DSS. SupportTypeShape2(i);
103 if(aSupTyp == BRepExtrema_IsVertex) {
104 BB.Add(myShape, DSS.SupportOnShape2(i));
105 }
106 else {
107 gp_Pnt p(.5*(p1.XYZ()+p2.XYZ()));
108 BRepBuilderAPI_MakeVertex mkV(p);
109 BB.Add(myShape, mkV.Vertex());
110
111 if (!myMapGener.IsBound(DSS. SupportOnShape1(i))) {
49b0c452 112
7fd59977 113 TopTools_ListOfShape aListOfShape1;
114 myMapGener.Bind(DSS.SupportOnShape1(i), aListOfShape1);
115 }
116 myMapGener(DSS.SupportOnShape1(i)).Append(mkV.Vertex());
117
118 if (!myMapGener.IsBound(DSS.SupportOnShape2(i))) {
49b0c452 119
7fd59977 120 TopTools_ListOfShape aListOfShape2;
121 myMapGener.Bind(DSS.SupportOnShape2(i), aListOfShape2);
122 }
123 myMapGener(DSS.SupportOnShape2(i)).Append(mkV.Vertex());
124
125 }
126
127 }
128 }
129 }
130 }
131
132 Done();
133 return;
134 }
7fd59977 135 Build();
136
137 Standard_Boolean bcw = BuilderCanWork();
138
139 if ( ! bcw ) return;
140
141 BRep_Builder BB;
142 BB.MakeCompound(TopoDS::Compound(myShape));
143 TopTools_ListIteratorOfListOfShape itloe(SectionEdges());
144
145 if(itloe.More()) {
146
147 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
148
149 // try to make wire from set of edges
150 TopTools_ListOfShape LOEdge;
151 TopTools_ListOfShape LOSEdge;
152 Standard_Integer nbe = 0;
153 TopoDS_Shape aux;
154 TopExp_Explorer Ex;
155 BB.MakeCompound(TopoDS::Compound(aux));
156 for(Ex.Init(myShape,TopAbs_EDGE); Ex.More(); Ex.Next()) {
157 LOEdge.Append(Ex.Current());
158 LOSEdge.Append(Ex.Current());
159 nbe++;
160 }
161 BRepAlgo_EdgeConnector EC;
162 TopoDS_Shape se = LOEdge.First();
163 EC.Add(LOEdge);
164 EC.AddStart(LOSEdge);
165 const TopTools_ListOfShape& LOWire = EC.MakeBlock();
166 TopTools_ListIteratorOfListOfShape its;
167 for(its.Initialize(LOWire);its.More();its.Next()) {
168 BB.Add(aux,its.Value());
169 }
170 for(Ex.Init(aux,TopAbs_EDGE); Ex.More(); Ex.Next()) {
171 nbe--;
172 }
173 if(nbe == 0) myShape = aux;
174
175 }
176 else {
177 // check if there are new vertices - IFV
178
179 Standard_Integer nbp = QANewModTopOpe_Tools::NbPoints(myDSFiller);
180
181 if(nbp > 0) {
182
183 TopoDS_Shape aux1, aux2;
184 BB.MakeCompound(TopoDS::Compound(aux1));
185 BB.MakeCompound(TopoDS::Compound(aux2));
186
187 BB.Add(aux1, myS1);
188 BB.Add(aux1, myS2);
189
190 Standard_Integer i;
191 Standard_Real maxtol = 0., tol;
192
193 for(i = 1; i <= nbp; i++) {
194 TopoDS_Vertex aVertex=
195 TopoDS::Vertex(QANewModTopOpe_Tools::NewVertex(myDSFiller, i));
196
197 tol=BRep_Tool::Tolerance(aVertex);
198 if(tol > maxtol) maxtol = tol;
199 BB.Add(aux2, aVertex);
200 }
201
202 BRepExtrema_DistShapeShape DSS(aux1, aux2);
203 if(DSS.IsDone() && DSS.NbSolution() > 0) {
204 Standard_Integer nbs = DSS.NbSolution();
205 Standard_Real mindist = DSS.Value();
206 if(mindist <= maxtol) {
207 tol = maxtol*maxtol;
208
209 TopTools_MapOfShape aMap;
210
211 for(i = 1; i <= nbs; i++) {
212 gp_Pnt p1 = DSS.PointOnShape1(i);
213 gp_Pnt p2 = DSS.PointOnShape2(i);
214 if(p1.SquareDistance(p2) > tol) continue;
215 BRepExtrema_SupportType aSupTyp = DSS.SupportTypeShape1(i);
216 TopoDS_Vertex aVertex;
217 if(aSupTyp == BRepExtrema_IsVertex) {
218 aVertex = TopoDS::Vertex(DSS.SupportOnShape1(i));
219 TopoDS_Iterator anIter(myShape);
220 Standard_Boolean anIsNew = Standard_True;
221 for(; anIter.More(); anIter.Next()) {
222 if(BRepTools::Compare(aVertex, TopoDS::Vertex(anIter.Value()))) {
223 anIsNew = Standard_False;
224 break;
225 }
226 }
227 if(anIsNew) {
228 BB.Add(myShape, aVertex);
229 }
230 }
231 else {
232 aVertex = TopoDS::Vertex(DSS.SupportOnShape2(i));
233 if(aMap.Add(aVertex)) BB.Add(myShape, aVertex);
234 if (!myMapGener.IsBound(DSS.SupportOnShape1(i))) {
235 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(DSS.SupportOnShape1(i), TopTools_ListOfShape());
236 TopTools_ListOfShape aListOfShape3;
237 myMapGener.Bind(DSS.SupportOnShape1(i), aListOfShape3);
238 }
239 myMapGener(DSS.SupportOnShape1(i)).Append(aVertex);
240
241 }
242 } // end for
243 }
244 }
245 }
246 }
247
248
249 Done();
250
251}
252
253//=======================================================================
254//function : Generated
255//purpose : gives list of shape generated from shape S
256//=======================================================================
257const TopTools_ListOfShape& QANewModTopOpe_Intersection::Generated(const TopoDS_Shape& theS)
258{
259 myGenerated.Clear();
260
261 if(theS.ShapeType() == TopAbs_FACE || theS.ShapeType() == TopAbs_EDGE) {
262 if (BRepAlgoAPI_BooleanOperation::HasGenerated()) {
263 const TopTools_ListOfShape &aLOfShape =
264 BRepAlgoAPI_BooleanOperation::Generated(theS);
265 TopTools_ListIteratorOfListOfShape anIter(aLOfShape);
266
267 for (; anIter.More(); anIter.Next()) {
268 const TopoDS_Shape &aGenShape = anIter.Value();
269
270 if (aGenShape.ShapeType() == TopAbs_VERTEX)
271 continue;
272
273 myGenerated.Append(aGenShape);
274 }
275 }
276
277 if(myMapGener.IsBound(theS)) {
278 TopTools_ListIteratorOfListOfShape anIter(myMapGener(theS));
279
280 for(; anIter.More(); anIter.Next())
281 myGenerated.Append(anIter.Value());
282 }
283 }
284
285 return myGenerated;
286
287}
288
289//=======================================================================
290//function : HasGenerated
291//purpose :
292//=======================================================================
293Standard_Boolean QANewModTopOpe_Intersection::HasGenerated() const
294{
295 Standard_Boolean aHasGenerated = Standard_False;
296
297 if (BRepAlgoAPI_BooleanOperation::HasGenerated()) {
298 aHasGenerated = Standard_True;
299 }
300 else {
301 aHasGenerated = !myMapGener.IsEmpty();
302 }
303 return aHasGenerated;
304}
305
306
307//=======================================================================
308//function : IsDeleted
309//purpose :
310//=======================================================================
311Standard_Boolean QANewModTopOpe_Intersection::IsDeleted(const TopoDS_Shape& aS)
312{
313 if(BRepAlgoAPI_BooleanOperation::IsDeleted(aS))
314 return Standard_True;
315
316 if(myMapGener.IsBound(aS))
317 return Standard_False;
318 return Standard_True;
319}
320
321//=======================================================================
322//function : HasDeleted
323//purpose :
324//=======================================================================
325Standard_Boolean QANewModTopOpe_Intersection::HasDeleted() const
326{
49b0c452 327 const TopoDS_Shape& myS1=myArguments.First();
328 const TopoDS_Shape& myS2=myTools.First();
329
7fd59977 330 TopExp_Explorer anExp;
331
332 for(Standard_Integer argit = 0; argit < 2; argit++) {
333 Standard_Boolean bTillVertex = Standard_True;
334
335 if(argit == 0)
336 anExp.Init(myS1, TopAbs_FACE);
337 else
338 anExp.Init(myS2, TopAbs_FACE);
339
340 if(anExp.More())
341 bTillVertex = Standard_False;
342 Standard_Integer nb = (bTillVertex) ? 3 : 2;
343
344 for(Standard_Integer i = 0; i < nb; i++) {
345 TopAbs_ShapeEnum aType = (i == 0) ? TopAbs_FACE : ((i == 1) ? TopAbs_EDGE : TopAbs_VERTEX);
346
347 if(argit == 0)
348 anExp.Init(myS1, aType);
349 else
350 anExp.Init(myS2, aType);
351
352 for(; anExp.More(); anExp.Next()) {
353 if(!myMapGener.IsBound(anExp.Current())) {
354 return Standard_True;
355 }
356 }
357 }
358 }
359 return Standard_False;
360}