0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BOPTools / BOPTools_AlgoTools_2.cxx
CommitLineData
b311480e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
7fd59977 15
42cf5bc1 16#include <BOPTools_AlgoTools.hxx>
17#include <BRep_Builder.hxx>
18#include <BRep_Tool.hxx>
19#include <BRepAdaptor_Curve.hxx>
20#include <BRepBuilderAPI_MakeEdge.hxx>
21#include <Geom_Curve.hxx>
22#include <GeomAbs_CurveType.hxx>
23#include <gp_Pnt.hxx>
24#include <IntTools_Context.hxx>
25#include <IntTools_Curve.hxx>
26#include <IntTools_Range.hxx>
df017cc9 27#include <Precision.hxx>
7fd59977 28#include <TopoDS.hxx>
4e57c75e 29#include <TopoDS_Edge.hxx>
42cf5bc1 30#include <TopoDS_Face.hxx>
4e57c75e 31#include <TopoDS_Iterator.hxx>
42cf5bc1 32#include <TopoDS_Shape.hxx>
33#include <TopoDS_Shell.hxx>
34#include <TopoDS_Solid.hxx>
35#include <TopoDS_Vertex.hxx>
7fd59977 36
4e57c75e 37static
38 void TreatCompound(const TopoDS_Shape& theC1,
39 BOPCol_ListOfShape& theLSX);
7fd59977 40
7fd59977 41//=======================================================================
42// function: UpdateVertex
43// purpose:
44//=======================================================================
505abfb8 45void BOPTools_AlgoTools::UpdateVertex
46 (const TopoDS_Vertex& aVF,
47 const TopoDS_Vertex& aNewVertex)
7fd59977 48{
49 Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
50 //
51 gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
52 gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
53 aTolVF=BRep_Tool::Tolerance(aVF);
54 aTolNewVertex=BRep_Tool::Tolerance(aNewVertex);
55
56 aDist=aPVF.Distance(aPNewVertex);
57 aNewTol=aDist+aTolNewVertex;
58
59 if (aNewTol>aTolVF) {
60 BRep_Builder BB;
61 BB.UpdateVertex (aVF, aNewTol+aDTol);
62 }
63}
4e57c75e 64
7fd59977 65//=======================================================================
66// function: UpdateVertex
67// purpose:
68//=======================================================================
505abfb8 69void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
70 const Standard_Real aT,
71 const TopoDS_Vertex& aV)
7fd59977 72{
73 Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
74 gp_Pnt aPc;
75
76 gp_Pnt aPv=BRep_Tool::Pnt(aV);
77 aTolV=BRep_Tool::Tolerance(aV);
78
94f71cad 79 GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
80 aCA.D0(aT, aPc);
7fd59977 81 aDist=aPv.Distance(aPc);
82 if (aDist>aTolV) {
83 BRep_Builder BB;
84 BB.UpdateVertex (aV, aDist+aDTol);
85 }
86}
87//
88//=======================================================================
89// function: UpdateVertex
90// purpose:
91//=======================================================================
505abfb8 92void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
93 const Standard_Real aT,
94 const TopoDS_Vertex& aV)
7fd59977 95{
96 Standard_Real aTolV, aDist, aDTol=1.e-12;
97 gp_Pnt aPc;
98
99 gp_Pnt aPv=BRep_Tool::Pnt(aV);
100 aTolV=BRep_Tool::Tolerance(aV);
101
94f71cad 102 GeomAdaptor_Curve aCA( aC.Curve() );
103 aCA.D0(aT, aPc);
7fd59977 104 aDist=aPv.Distance(aPc);
105 if (aDist>aTolV) {
106 BRep_Builder BB;
107 BB.UpdateVertex (aV, aDist+aDTol);
108 }
109}
110//=======================================================================
111// function: MakeSectEdge
112// purpose:
113//=======================================================================
505abfb8 114void BOPTools_AlgoTools::MakeSectEdge(const IntTools_Curve& aIC,
115 const TopoDS_Vertex& aV1,
116 const Standard_Real aP1,
117 const TopoDS_Vertex& aV2,
118 const Standard_Real aP2,
119 TopoDS_Edge& aNewEdge)
7fd59977 120{
121 Handle(Geom_Curve) aC=aIC.Curve ();
122
123 BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
124
125 const TopoDS_Edge& aE=TopoDS::Edge(aMakeEdge.Shape());
126 //
127 // Range must be as it was !
128 BRep_Builder aBB;
129 aBB.Range (aE, aP1, aP2);
130 //
131 aNewEdge=aE;
132
133}
134
135//=======================================================================
136// function: MakeSplitEdge
137// purpose:
138//=======================================================================
505abfb8 139void BOPTools_AlgoTools::MakeSplitEdge(const TopoDS_Edge& aE,
140 const TopoDS_Vertex& aV1,
141 const Standard_Real aP1,
142 const TopoDS_Vertex& aV2,
143 const Standard_Real aP2,
144 TopoDS_Edge& aNewEdge)
7fd59977 145{
505abfb8 146 Standard_Real aTol;//f, l,
7fd59977 147 aTol=BRep_Tool::Tolerance(aE);
148 //
7fd59977 149 TopoDS_Edge E=aE;
150 E.EmptyCopy();
505abfb8 151 //
7fd59977 152 BRep_Builder BB;
153 BB.Add (E, aV1);
154 BB.Add (E, aV2);
155 BB.Range(E, aP1, aP2);
156 BB.UpdateEdge(E, aTol);
157 aNewEdge=E;
158}
159
160//=======================================================================
161// function: MakeNewVertex
162// purpose:
163//=======================================================================
505abfb8 164void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Vertex& aV1,
165 const TopoDS_Vertex& aV2,
166 TopoDS_Vertex& aNewVertex)
7fd59977 167{
168 gp_Pnt aPnt1=BRep_Tool::Pnt(aV1);
169 Standard_Real aTol1=BRep_Tool::Tolerance(aV1);
4e57c75e 170
7fd59977 171 gp_Pnt aPnt2=BRep_Tool::Pnt(aV2);
172 Standard_Real aTol2=BRep_Tool::Tolerance(aV2);
173
174 Standard_Real aMaxTol, aDist;
4e57c75e 175
7fd59977 176 aDist=aPnt1.Distance(aPnt2);
177 aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
178 aMaxTol=aMaxTol+0.5*aDist;
4e57c75e 179
7fd59977 180 const gp_XYZ& aXYZ1=aPnt1.XYZ();
181 const gp_XYZ& aXYZ2=aPnt2.XYZ();
182 gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
4e57c75e 183
7fd59977 184 gp_Pnt aNewPnt(aNewXYZ);
185 BRep_Builder aBB;
186 aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
187}
188 //=======================================================================
189// function: MakeNewVertex
190// purpose:
191//=======================================================================
505abfb8 192void BOPTools_AlgoTools::MakeNewVertex(const gp_Pnt& aP,
193 const Standard_Real aTol,
194 TopoDS_Vertex& aNewVertex)
7fd59977 195{
196 BRep_Builder aBB;
197 aBB.MakeVertex (aNewVertex, aP, aTol);
198}
199
200//=======================================================================
201// function: MakeNewVertex
202// purpose:
203//=======================================================================
505abfb8 204void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
205 const Standard_Real aParm1,
206 const TopoDS_Edge& aE2,
207 const Standard_Real aParm2,
208 TopoDS_Vertex& aNewVertex)
7fd59977 209{
210 Standard_Real aTol1, aTol2, aMaxTol, aDist;
211 gp_Pnt aPnt1, aPnt2;
212
213 PointOnEdge (aE1, aParm1, aPnt1);
214 PointOnEdge (aE2, aParm2, aPnt2);
215
216 aTol1=BRep_Tool::Tolerance(aE1);
217 aTol2=BRep_Tool::Tolerance(aE2);
218
219 aDist=aPnt1.Distance(aPnt2);
220 aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
221 aMaxTol=aMaxTol+0.5*aDist;
222
223 const gp_XYZ& aXYZ1=aPnt1.XYZ();
224 const gp_XYZ& aXYZ2=aPnt2.XYZ();
225 gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
4e57c75e 226
7fd59977 227 gp_Pnt aNewPnt(aNewXYZ);
228 BRep_Builder aBB;
229 aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
230}
231//=======================================================================
232// function: MakeNewVertex
233// purpose:
234//=======================================================================
505abfb8 235void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
236 const Standard_Real aParm1,
237 const TopoDS_Face& aF1,
238 TopoDS_Vertex& aNewVertex)
7fd59977 239{
240 Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12;
241 gp_Pnt aPnt;
242
243 PointOnEdge (aE1, aParm1, aPnt);
244
245 aTol1=BRep_Tool::Tolerance(aE1);
246 aTol2=BRep_Tool::Tolerance(aF1);
247 //
248 //aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
249 aMaxTol=aTol1+aTol2+delta;
250 //
251 BRep_Builder aBB;
252 aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
253}
254
255//=======================================================================
256// function: PointOnEdge
257// purpose:
258//=======================================================================
505abfb8 259void BOPTools_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
260 const Standard_Real aParm,
261 gp_Pnt& aPnt)
7fd59977 262{
263 Standard_Real f, l;
264 Handle(Geom_Curve) C1=BRep_Tool::Curve(aE, f, l);
265 C1->D0(aParm, aPnt);
266}
267
7fd59977 268//=======================================================================
269//function : CorrectRange
270//purpose :
271//=======================================================================
505abfb8 272void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE1,
273 const TopoDS_Edge& aE2,
274 const IntTools_Range& aSR,
275 IntTools_Range& aNewSR)
7fd59977 276{
277 Standard_Integer i;
278 Standard_Real aRes, aTolE1, aTolE2, aTF, aTL, dT;
279 BRepAdaptor_Curve aBC;
280 GeomAbs_CurveType aCT;
281 gp_Pnt aP;
282 gp_Vec aDer;
283 //
284 aNewSR=aSR;
285 //
7fd59977 286 aBC.Initialize(aE1);
287 aCT=aBC.GetType();
288 if (aCT==GeomAbs_Line) {
289 return;
290 }
7fd59977 291 //
292 dT=Precision::PConfusion();
293 aTF=aSR.First();
294 aTL=aSR.Last();
295 //
7fd59977 296 aTolE1=BRep_Tool::Tolerance(aE1);
297 aTolE2=BRep_Tool::Tolerance(aE2);
298 //
299 for(i=0; i<2; ++i) {
300 aRes = 2.*(aTolE1 + aTolE2);
301 //
302 if (aCT==GeomAbs_BezierCurve ||
4e57c75e 303 aCT==GeomAbs_BSplineCurve||
304 aCT==GeomAbs_OtherCurve) {
7fd59977 305
306 if(!i){
4e57c75e 307 aBC.D1 (aTF, aP, aDer);
7fd59977 308 }
309 else {
4e57c75e 310 aBC.D1 (aTL, aP, aDer);
7fd59977 311 }
312 //
313 Standard_Real aMgn = aDer.Magnitude();
314
315 if(aMgn > 1.e-12) {
4e57c75e 316 aRes = aRes/aMgn ;
7fd59977 317 }
318 else {
4e57c75e 319 aRes = aBC.Resolution(aRes);
7fd59977 320 }
321 } // if (aCT==GeomAbs_BezierCurve||...
322 else {
323 aRes = aBC.Resolution(aRes);
324 }
325 //
326 if(!i) {
327 aNewSR.SetFirst (aTF+aRes);
328 }
329 else {
330 aNewSR.SetLast (aTL-aRes);
331 }
332 //
333 if ((aNewSR.Last()-aNewSR.First()) < dT) {
334 aNewSR=aSR;
335 }
336 //aNewSR=((aNewSR.Last()-aNewSR.First()) < dT) ? aSR : aNewSR;
337 }
338}
4e57c75e 339
7fd59977 340//=======================================================================
341//function : CorrectRange
342//purpose :
343//=======================================================================
505abfb8 344void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
345 const TopoDS_Face& aF,
346 const IntTools_Range& aSR,
347 IntTools_Range& aNewSR)
7fd59977 348{
349 Standard_Integer i;
350 Standard_Real aRes, aTolF, aTF, aTL, dT;
351 BRepAdaptor_Curve aBC;
352 GeomAbs_CurveType aCT;
353 gp_Pnt aP;
354 gp_Vec aDer;
355 //
356 aNewSR=aSR;
357 //
358 dT=Precision::PConfusion();
359 aTF=aSR.First();
360 aTL=aSR.Last();
361 //
362 aBC.Initialize(aE);
363 aCT=aBC.GetType();
364 //
365 aTolF=BRep_Tool::Tolerance(aF);
366 //
367 for(i=0; i<2; ++i) {
368 aRes =aTolF;
369
370 if (aCT==GeomAbs_BezierCurve ||
4e57c75e 371 aCT==GeomAbs_BSplineCurve||
372 aCT==GeomAbs_OtherCurve) {
7fd59977 373
374 if(!i){
4e57c75e 375 aBC.D1 (aTF, aP, aDer);
7fd59977 376 }
377 else {
4e57c75e 378 aBC.D1 (aTL, aP, aDer);
7fd59977 379 }
380 //
381 Standard_Real aMgn = aDer.Magnitude();
382
383 if(aMgn > 1.e-12) {
4e57c75e 384 aRes = aRes/aMgn ;
7fd59977 385 }
386 else {
4e57c75e 387 aRes = aBC.Resolution(aRes);
7fd59977 388 }
389 } // if (aCT==GeomAbs_BezierCurve||...
390 else {
391 aRes = aBC.Resolution(aRes);
392 }
393 //
394 if(!i) {
395 aNewSR.SetFirst (aTF+aRes);
396 }
397 else {
398 aNewSR.SetLast (aTL-aRes);
399 }
400 //
401 if ((aNewSR.Last()-aNewSR.First()) < dT) {
402 aNewSR=aSR;
403 }
404 }
405}
7fd59977 406//=======================================================================
4e57c75e 407//function : Dimension
7fd59977 408//purpose :
409//=======================================================================
505abfb8 410Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
7fd59977 411{
1d47d8d0 412 Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
4e57c75e 413 TopAbs_ShapeEnum aTS;
414 BOPCol_ListOfShape aLS;
415 BOPCol_ListIteratorOfListOfShape aIt;
416 //
417 aTS=theS.ShapeType();
418 if (aTS!=TopAbs_COMPOUND) {
419 switch (aTS) {
420 case TopAbs_EDGE:
421 case TopAbs_WIRE:
422 iRet=1;
423 break;
424 case TopAbs_FACE:
425 case TopAbs_SHELL:
426 iRet=2;
427 break;
428 case TopAbs_SOLID:
429 case TopAbs_COMPSOLID:
430 iRet=3;
431 break;
432 default:
433 iRet=0;
434 }
435 return iRet;
7fd59977 436 }
4e57c75e 437 //
438 iRet=-1;
439 TreatCompound(theS, aLS);
440 if(aLS.IsEmpty()) {
441 iRet = -2; //empty compound
442 return iRet;
7fd59977 443 }
4e57c75e 444 aIt.Initialize(aLS);
445 for (i=0; aIt.More(); aIt.Next()) {
446 const TopoDS_Shape& aSx=aIt.Value();
447 iRx=Dimension(aSx);
448 if (!i) {
449 iRx0=iRx;
450 i=1;
451 continue;
452 }
453 if (iRx!=iRx0) {
454 return iRet;// -1
455 }
7fd59977 456 }
4e57c75e 457 return iRx;
458}
7fd59977 459
4e57c75e 460//=======================================================================
461//function : TreatCompound
462//purpose :
463//=======================================================================
505abfb8 464void TreatCompound(const TopoDS_Shape& theC1,
465 BOPCol_ListOfShape& theLSX)
4e57c75e 466{
467 Standard_Integer aNbC1;
468 TopAbs_ShapeEnum aType;
469 BOPCol_ListOfShape aLC, aLC1;
470 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
471 TopoDS_Iterator aItC;
472 //
473 aLC.Append (theC1);
302f96fb 474 for(;;) {
4e57c75e 475 aLC1.Clear();
476 aIt.Initialize(aLC);
477 for (; aIt.More(); aIt.Next()) {
478 const TopoDS_Shape& aC=aIt.Value(); //C is compound
479 //
480 aItC.Initialize(aC);
481 for (; aItC.More(); aItC.Next()) {
482 const TopoDS_Shape& aS=aItC.Value();
483 aType=aS.ShapeType();
484 if (aType==TopAbs_COMPOUND) {
485 aLC1.Append(aS);
486 }
487 else {
488 theLSX.Append(aS);
489 }
490 }
491 }
492 //
493 aNbC1=aLC1.Extent();
494 if (!aNbC1) {
495 break;
496 }
497 //
498 aLC.Clear();
499 aIt.Initialize(aLC1);
500 for (; aIt.More(); aIt.Next()) {
501 const TopoDS_Shape& aSC=aIt.Value();
502 aLC.Append(aSC);
503 }
504 }// while(1)
7fd59977 505}