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