0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / BOPTools / BOPTools_AlgoTools3D.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
4e57c75e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
4e57c75e 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.
4e57c75e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
4e57c75e 14
4e57c75e 15
6303cb12 16#include <Bnd_Box.hxx>
42cf5bc1 17#include <BOPTools_AlgoTools2D.hxx>
18#include <BOPTools_AlgoTools3D.hxx>
19#include <BRep_Builder.hxx>
42cf5bc1 20#include <BRep_TEdge.hxx>
21#include <BRep_TFace.hxx>
22#include <BRep_Tool.hxx>
42cf5bc1 23#include <BRepTools.hxx>
4e57c75e 24#include <Geom2d_Curve.hxx>
4e57c75e 25#include <Geom2d_Line.hxx>
42cf5bc1 26#include <Geom2d_TrimmedCurve.hxx>
42cf5bc1 27#include <Geom2dHatch_Hatcher.hxx>
4e57c75e 28#include <Geom_BezierSurface.hxx>
42cf5bc1 29#include <Geom_BSplineSurface.hxx>
6303cb12 30#include <Geom_RectangularTrimmedSurface.hxx>
42cf5bc1 31#include <Geom_Surface.hxx>
d476fc37 32#include <Geom2dAPI_ProjectPointOnCurve.hxx>
42cf5bc1 33#include <gp_Dir.hxx>
34#include <gp_Dir2d.hxx>
42cf5bc1 35#include <gp_Pnt.hxx>
36#include <gp_Pnt2d.hxx>
37#include <gp_Vec.hxx>
38#include <gp_Vec2d.hxx>
6303cb12 39#include <HatchGen_Domain.hxx>
42cf5bc1 40#include <IntTools_Context.hxx>
41#include <IntTools_Tools.hxx>
42#include <Poly_Triangulation.hxx>
43#include <TopExp.hxx>
44#include <TopExp_Explorer.hxx>
6303cb12 45#include <TopoDS.hxx>
6303cb12 46#include <TopoDS_Edge.hxx>
47#include <TopoDS_Face.hxx>
42cf5bc1 48#include <TopoDS_Shape.hxx>
1155d05a 49#include <TopTools_IndexedMapOfShape.hxx>
4e57c75e 50
4e57c75e 51static void Add(const TopoDS_Shape& aS,
1155d05a 52 TopTools_IndexedMapOfShape& myShapes,
4e57c75e 53 Standard_Boolean& bHasGeometry);
54static
55 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
56
57//=======================================================================
58//function : DoSplitSEAMOnFace
59//purpose :
60//=======================================================================
d476fc37 61Standard_Boolean BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
62 const TopoDS_Face& aF)
4e57c75e 63{
362dec17 64 Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
d1b591e5 65 Standard_Real anUPeriod = 0., anVPeriod = 0.;
66 Standard_Real aTol, a, b, aT, anU, dU, anU1;
362dec17 67 Standard_Real aScPr, anV, dV, anV1;
6303cb12 68 Standard_Real aUmin, aUmax, aVmin, aVmax;
4e57c75e 69 gp_Pnt2d aP2D;
70 gp_Vec2d aVec2D;
71 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
72 Handle(Geom2d_Curve) C2D1;
73 Handle(Geom2d_Line) aLD1;
74 Handle(Geom_Surface) aS;
75 BRep_Builder BB;
76 TopoDS_Edge aSp;
77 //
362dec17 78 bIsLeft = Standard_False;
4e57c75e 79 aSp=aSplit;
80 aSp.Orientation(TopAbs_FORWARD);
4e57c75e 81 aTol=BRep_Tool::Tolerance(aSp);
fe343049 82 //
4e57c75e 83 aS=BRep_Tool::Surface(aF);
6303cb12 84 //
85 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
86 //
d1b591e5 87
88 bIsUPeriodic = aS->IsUClosed();
89 bIsVPeriodic = aS->IsVClosed();
90
91 if (bIsUPeriodic)
92 anUPeriod = aUmax - aUmin;
93 if (bIsVPeriodic)
94 anVPeriod = aVmax - aVmin;
95
fe343049 96 //
97 if (!bIsUPeriodic && !bIsVPeriodic) {
d1b591e5 98
6303cb12 99 Handle(Geom_RectangularTrimmedSurface) aRTS;
d1b591e5 100 aRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
4e57c75e 101 //
d1b591e5 102 if (aRTS.IsNull())
103 return Standard_False;
104
105 else {
6303cb12 106 Handle(Geom_Surface) aSB;
107 //
d1b591e5 108 aSB = aRTS->BasisSurface();
109 bIsUPeriodic = aSB->IsUPeriodic();
110 bIsVPeriodic = aSB->IsVPeriodic();
6303cb12 111 //
d1b591e5 112
113 if (bIsUPeriodic || bIsVPeriodic)
114 {
115 anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
116 anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
6303cb12 117 }
d1b591e5 118 else
119 {
120 Standard_Boolean bIsUClosed = aSB->IsUClosed();
121 Standard_Boolean bIsVClosed = aSB->IsVClosed();
122 Standard_Real aGlobalUmin, aGlobalUmax, aGlobalVmin, aGlobalVmax;
123 aSB->Bounds(aGlobalUmin, aGlobalUmax, aGlobalVmin, aGlobalVmax);
124
125 if (bIsUClosed &&
126 Abs(aUmin - aGlobalUmin) < aTol &&
127 Abs(aUmax - aGlobalUmax) < aTol)
128 {
129 bIsUPeriodic = Standard_True;
130 anUPeriod = aUmax - aUmin;
131 }
132 if (bIsVClosed &&
133 Abs(aVmin - aGlobalVmin) < aTol &&
134 Abs(aVmax - aGlobalVmax) < aTol)
135 {
136 bIsVPeriodic = Standard_True;
137 anVPeriod = aVmax - aVmin;
138 }
6303cb12 139 }
d1b591e5 140
141 if (!(bIsUPeriodic || bIsVPeriodic)) {
142 return Standard_False;
6303cb12 143 }
d1b591e5 144 } //if !RTS.IsNull
4e57c75e 145 }
146 //
6303cb12 147 //---------------------------------------------------
4e57c75e 148 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
149 //
150 aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
151 C2D1->D1(aT, aP2D, aVec2D);
fe343049 152 gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
4e57c75e 153 //
fe343049 154 anU=aP2D.X();
155 anV=aP2D.Y();
4e57c75e 156 //
fe343049 157 anU1=anU;
158 anV1=anV;
4e57c75e 159 //
0929d0ef 160 GeomAdaptor_Surface aGAS(aS);
161 dU = aGAS.UResolution(aTol);
162 dV = aGAS.VResolution(aTol);
163 //
fe343049 164 if (anUPeriod > 0.){
6303cb12 165 if (fabs (anU-aUmin) < dU) {
fe343049 166 bIsLeft=Standard_True;
167 anU1=anU+anUPeriod;
168 }
6303cb12 169 else if (fabs (anU-aUmax) < dU) {
fe343049 170 bIsLeft=Standard_False;
171 anU1=anU-anUPeriod;
172 }
4e57c75e 173 }
fe343049 174 //
175 if (anVPeriod > 0.) {
6303cb12 176 if (fabs (anV-aVmin) < dV) {
fe343049 177 bIsLeft=Standard_True;
178 anV1=anV+anVPeriod;
179 }
6303cb12 180 else if (fabs (anV-aVmax) < dV) {
fe343049 181 bIsLeft=Standard_False;
182 anV1=anV-anVPeriod;
183 }
4e57c75e 184 }
fe343049 185 //
186 if (anU1==anU && anV1==anV) {
d476fc37 187 return Standard_False;
4e57c75e 188 }
189 //
fe343049 190 aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
191 //
4e57c75e 192 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
362dec17 193 Handle(Geom2d_TrimmedCurve) aC1 =
194 new Geom2d_TrimmedCurve(aTmpC1, a, b);
fe343049 195 //
4e57c75e 196 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
362dec17 197 Handle(Geom2d_TrimmedCurve) aC2 =
198 new Geom2d_TrimmedCurve(aTmpC2, a, b);
fe343049 199 gp_Vec2d aTrV(anU1-anU, anV1-anV);
4e57c75e 200 aC2->Translate(aTrV);
201 //
202 if (!bIsLeft) {
203 if (aScPr<0.) {
204 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
205 }
206 else {
207 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
208 }
209 }
210 else {
211 if (aScPr<0.) {
212 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
213 }
214 else {
215 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
216 }
217 }
d476fc37 218 return Standard_True;
4e57c75e 219}
d476fc37 220
221//=======================================================================
222//function : DoSplitSEAMOnFace
223//purpose :
224//=======================================================================
225Standard_Boolean BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& theEOrigin,
226 const TopoDS_Edge& theESplit,
227 const TopoDS_Face& theFace)
228{
229 if (!BRep_Tool::IsClosed (theEOrigin, theFace))
230 return Standard_False;
231
232 if (BRep_Tool::IsClosed (theESplit, theFace))
233 return Standard_True;
234
235 TopoDS_Edge aESplit = theESplit;
236 aESplit.Orientation (TopAbs_FORWARD);
237
238 TopoDS_Face aFace = theFace;
239 aFace.Orientation (TopAbs_FORWARD);
240
241 Standard_Real aTS1, aTS2;
242 Handle(Geom2d_Curve) aC2DSplit = BRep_Tool::CurveOnSurface (aESplit, aFace, aTS1, aTS2);
243 if (aC2DSplit.IsNull())
244 return Standard_False;
245
246 Standard_Real aT1, aT2;
247 Handle(Geom2d_Curve) aC2D1 = BRep_Tool::CurveOnSurface (
248 TopoDS::Edge (theEOrigin.Oriented (TopAbs_FORWARD)), aFace, aT1, aT2);
249 Handle(Geom2d_Curve) aC2D2 = BRep_Tool::CurveOnSurface (
250 TopoDS::Edge (theEOrigin.Oriented (TopAbs_REVERSED)), aFace, aT1, aT2);
251
252 Standard_Real aT = BOPTools_AlgoTools2D::IntermediatePoint (aTS1, aTS2);
253 gp_Pnt2d aPMid;
254 gp_Vec2d aVTgt;
255 aC2DSplit->D1 (aT, aPMid, aVTgt);
256
257 // project on original 2d curves
258 Geom2dAPI_ProjectPointOnCurve aProjPC1, aProjPC2;
259 aProjPC1.Init (aPMid, aC2D1, aT1, aT2);
260 aProjPC2.Init (aPMid, aC2D2, aT1, aT2);
261
262 if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
263 return Standard_False;
264
265 Standard_Real aDist1 = aProjPC1.NbPoints() ? aProjPC1.LowerDistance() : RealLast();
266 Standard_Real aDist2 = aProjPC2.NbPoints() ? aProjPC2.LowerDistance() : RealLast();
267
268 if (aDist1 > Precision::PConfusion() && aDist2 > Precision::PConfusion())
269 return Standard_False;
270
271 // choose the closest and take corresponding point from the opposite
272 gp_Pnt2d aNewPnt = aDist1 < aDist2 ? aC2D2->Value (aProjPC1.LowerDistanceParameter()) :
273 aC2D1->Value (aProjPC2.LowerDistanceParameter());
274
275 Handle (Geom2d_Curve) aTmpC1 = Handle (Geom2d_Curve)::DownCast (aC2DSplit->Copy());
276 Handle (Geom2d_Curve) aTmpC2 = Handle (Geom2d_Curve)::DownCast (aC2DSplit->Copy());
277
278 Handle (Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve (aTmpC1, aTS1, aTS2);
279 Handle (Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve (aTmpC2, aTS1, aTS2);
280
281 gp_Vec2d aTrVec (aPMid, aNewPnt);
282 aC2->Translate (aTrVec);
283
284 gp_Pnt2d aPProj;
285 gp_Vec2d aVTgtOrigin;
286 if (aDist1 < aDist2)
287 {
288 aC2D1->D1 (aProjPC1.LowerDistanceParameter(), aPProj, aVTgtOrigin);
289 }
290 else
291 {
292 aC2D2->D1 (aProjPC2.LowerDistanceParameter(), aPProj, aVTgtOrigin);
293 }
294
295 Standard_Real aDot = aVTgt.Dot (aVTgtOrigin);
296
297 if ((aDist1 < aDist2) == (aDot > 0))
298 {
299 BRep_Builder().UpdateEdge (aESplit, aC1, aC2, aFace, BRep_Tool::Tolerance (aESplit));
300 }
301 else
302 {
303 BRep_Builder().UpdateEdge (aESplit, aC2, aC1, aFace, BRep_Tool::Tolerance (aESplit));
304 }
305 return Standard_True;
306}
307
4e57c75e 308//=======================================================================
309//function : GetNormalToFaceOnEdge
310//purpose :
311//=======================================================================
362dec17 312void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
313 const TopoDS_Face& aF,
51db0179 314 gp_Dir& aDNF,
315 const Handle(IntTools_Context)& theContext)
4e57c75e 316{
317 Standard_Real aT, aT1, aT2;
318
319 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
320 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
321
51db0179 322 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF, theContext);
4e57c75e 323
324 if (aF.Orientation()==TopAbs_REVERSED){
325 aDNF.Reverse();
326 }
327}
4e57c75e 328//=======================================================================
329//function : GetNormalToFaceOnEdge
330//purpose :
331//=======================================================================
362dec17 332void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
333 const TopoDS_Face& aF1,
334 const Standard_Real aT,
51db0179 335 gp_Dir& aDNF1,
336 const Handle(IntTools_Context)& theContext)
4e57c75e 337{
338 Standard_Real U, V, aTolPC;
339 gp_Pnt2d aP2D;
340 gp_Pnt aP;
341 gp_Vec aD1U, aD1V;
342
343 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
344
345 Handle(Geom2d_Curve)aC2D1;
51db0179 346 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC, theContext);
4e57c75e 347
348 aC2D1->D0(aT, aP2D);
349 U=aP2D.X();
350 V=aP2D.Y();
351
352 aS1->D1(U, V, aP, aD1U, aD1V);
353 gp_Dir aDD1U(aD1U);
354 gp_Dir aDD1V(aD1V);
355
356 aDNF1=aDD1U^aDD1V;
357}
4e57c75e 358//=======================================================================
359//function : SenseFlag
360//purpose :
361//=======================================================================
362dec17 362Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
363 const gp_Dir& aDNF2)
4e57c75e 364{
365 Standard_Boolean bIsDirsCoinside;
362dec17 366 //
4e57c75e 367 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
368 if (!bIsDirsCoinside) {
369 return 0;
370 }
371
372 Standard_Real aScPr;
373
374 aScPr=aDNF1*aDNF2;
375 if (aScPr<0.) {
376 return -1;
377 }
378 else if (aScPr>0.) {
379 return 1;
380 }
381 return -1;
382}
4e57c75e 383//=======================================================================
384//function : GetNormalToSurface
385//purpose :
386//=======================================================================
362dec17 387Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface
388 (const Handle(Geom_Surface)& aS,
389 const Standard_Real U,
390 const Standard_Real V,
391 gp_Dir& aDNS)
4e57c75e 392{
4e57c75e 393 gp_Pnt aP;
394 gp_Vec aD1U, aD1V;
395
396 aS->D1(U, V, aP, aD1U, aD1V);
b7cd7c2b 397
398 Standard_Real aLenU = aD1U.SquareMagnitude();
399 if (aLenU < gp::Resolution())
400 return Standard_False;
401
402 Standard_Real aLenV = aD1V.SquareMagnitude();
403 if (aLenV < gp::Resolution())
404 return Standard_False;
405
406 gp_Dir aDD1U(aD1U);
407 gp_Dir aDD1V(aD1V);
408
409 Standard_Boolean bFlag = IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
410 if (!bFlag)
4e57c75e 411 return bFlag;
b7cd7c2b 412
413 aDNS = aDD1U^aDD1V;
4e57c75e 414 return bFlag;
415}
4e57c75e 416//=======================================================================
417//function : GetApproxNormalToFaceOnEdge
418//purpose :
419//=======================================================================
18c06690 420Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
362dec17 421 (const TopoDS_Edge& aE,
422 const TopoDS_Face& aF,
423 const Standard_Real aT,
424 gp_Pnt& aPNear,
425 gp_Dir& aDNF,
426 Standard_Real aDt2D)
4e57c75e 427{
4e57c75e 428 gp_Pnt2d aPx2DNear;
18c06690 429 Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge
430 (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
431 if (iErr != 1) {
432 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
4e57c75e 433
18c06690 434 BOPTools_AlgoTools3D::GetNormalToSurface
435 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
4e57c75e 436
18c06690 437 if (aF.Orientation()==TopAbs_REVERSED){
438 aDNF.Reverse();
439 }
4e57c75e 440 }
18c06690 441 //
442 return (iErr == 0);
4e57c75e 443}
4e57c75e 444//=======================================================================
445//function : GetApproxNormalToFaceOnEdge
446//purpose :
447//=======================================================================
18c06690 448Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
362dec17 449 (const TopoDS_Edge& aE,
450 const TopoDS_Face& aF,
451 const Standard_Real aT,
452 gp_Pnt& aPNear,
453 gp_Dir& aDNF,
80d55adf 454 const Handle(IntTools_Context)& theContext)
4e57c75e 455{
4e57c75e 456 gp_Pnt2d aPx2DNear;
18c06690 457 Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge
362dec17 458 (aE, aF, aT, aPx2DNear, aPNear, theContext);
18c06690 459 if (iErr != 1) {
460 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
4e57c75e 461
18c06690 462 BOPTools_AlgoTools3D::GetNormalToSurface
463 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
4e57c75e 464
18c06690 465 if (aF.Orientation()==TopAbs_REVERSED){
466 aDNF.Reverse();
467 }
468 }
469 //
470 return (iErr == 0);
471}
472//=======================================================================
473//function : GetApproxNormalToFaceOnEdge
474//purpose :
475//=======================================================================
476Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
477 (const TopoDS_Edge& aE,
478 const TopoDS_Face& aF,
479 const Standard_Real aT,
480 const Standard_Real theStep,
481 gp_Pnt& aPNear,
482 gp_Dir& aDNF,
80d55adf 483 const Handle(IntTools_Context)& theContext)
18c06690 484{
485 gp_Pnt2d aPx2DNear;
486 Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge
487 (aE, aF, aT, theStep, aPx2DNear, aPNear, theContext);
488 if (iErr != 1) {
489 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
4e57c75e 490
18c06690 491 BOPTools_AlgoTools3D::GetNormalToSurface
492 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
493
494 if (aF.Orientation()==TopAbs_REVERSED){
495 aDNF.Reverse();
496 }
4e57c75e 497 }
18c06690 498 //
499 return (iErr == 0);
4e57c75e 500}
4e57c75e 501//=======================================================================
502//function : PointNearEdge
503//purpose :
504//=======================================================================
18c06690 505Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
506 (const TopoDS_Edge& aE,
507 const TopoDS_Face& aF,
508 const Standard_Real aT,
509 const Standard_Real aDt2D,
510 gp_Pnt2d& aPx2DNear,
511 gp_Pnt& aPxNear)
4e57c75e 512{
513 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
514 GeomAbs_SurfaceType aTS;
515 Handle(Geom2d_Curve) aC2D;
516 Handle(Geom_Surface) aS;
517 //
518 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
18c06690 519 Standard_Integer iErr = aC2D.IsNull() ? 1 : 0;
520 if (iErr) {
521 return iErr;
4e57c75e 522 }
523 //
524 aS=BRep_Tool::Surface(aF);
525 //
526 gp_Pnt2d aPx2D;
527 gp_Vec2d aVx2D;
528 aC2D->D1 (aT, aPx2D, aVx2D);
529 gp_Dir2d aDx2D(aVx2D);
530
531 gp_Dir2d aDP;
532 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
533
534 if (aE.Orientation()==TopAbs_REVERSED){
535 aDP.Reverse();
536 }
537
538 if (aF.Orientation()==TopAbs_REVERSED) {
539 aDP.Reverse();
540 }
541 //
542 aETol = BRep_Tool::Tolerance(aE);
543 aFTol = BRep_Tool::Tolerance(aF);
f4ea2ca6 544 // NPAL19220
4e57c75e 545 GeomAdaptor_Surface aGAS(aS);
546 aTS=aGAS.GetType();
547 if (aTS==GeomAbs_BSplineSurface) {
548 if (aETol > 1.e-5) {
549 aFTol=aETol;
550 }
551 }
552 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
6303cb12 553 //
4e57c75e 554 if(aTS!=GeomAbs_Sphere) {
555 gp_Vec2d transVec( aDP );
556 transVal = aDt2D + aETol + aFTol;
557 if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
558 Standard_Real aR, dT;
559 //
560 gp_Cylinder aCyl=aGAS.Cylinder();
561 aR=aCyl.Radius();
562 dT=1.-transVal/aR;
563 if (dT>=-1 && dT<=1) {
564 dT=acos(dT);
565 transVal=dT;
566 }
567 }
568 //
569 transVec.Multiply(transVal);
570 aPx2DNear = aPx2D.Translated( transVec );
571 }
572 else {
362dec17 573 aPx2DNear.SetCoord
574 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
4e57c75e 575 }
576 }
577 else {
362dec17 578 aPx2DNear.SetCoord
579 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
4e57c75e 580 }
581 //
582 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
18c06690 583 return iErr;
4e57c75e 584}
4e57c75e 585//=======================================================================
586//function : PointNearEdge
587//purpose :
588//=======================================================================
18c06690 589Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
362dec17 590 (const TopoDS_Edge& aE,
591 const TopoDS_Face& aF,
592 const Standard_Real aT,
593 gp_Pnt2d& aPx2DNear,
594 gp_Pnt& aPxNear,
80d55adf 595 const Handle(IntTools_Context)& theContext)
4e57c75e 596{
f4ea2ca6 597 Standard_Real aTolE, aTolF, dTx, dT2D;
598 Handle(Geom_Surface) aS;
599 GeomAdaptor_Surface aGAS;
4e57c75e 600 //
f4ea2ca6 601 dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
602 //
603 aS = BRep_Tool::Surface(aF);
604 aGAS.Load(aS);
4e57c75e 605 if (aGAS.GetType()==GeomAbs_Cylinder ||
606 aGAS.GetType()==GeomAbs_Sphere) {
f4ea2ca6 607 dT2D=10.*dT2D;
18c06690 608 }
f4ea2ca6 609 //
4e57c75e 610 aTolE = BRep_Tool::Tolerance(aE);
611 aTolF = BRep_Tool::Tolerance(aF);
f4ea2ca6 612 dTx = 2.*(aTolE + aTolF);
613 if (dTx > dT2D) {
614 dT2D=dTx;
615 }
616 //
18c06690 617 Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge
362dec17 618 (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
18c06690 619 if ((iErr != 1) && !theContext->IsPointInOnFace(aF, aPx2DNear)) {
4e57c75e 620 gp_Pnt aP;
621 gp_Pnt2d aP2d;
4e57c75e 622 //
18c06690 623 iErr = BOPTools_AlgoTools3D::PointInFace
624 (aF, aE, aT, dT2D, aP, aP2d, theContext);
625 if (iErr == 0) {
626 aPxNear = aP;
627 aPx2DNear = aP2d;
51db0179 628 }
629 else {
18c06690 630 iErr = 2; // point is out of the face
51db0179 631 }
18c06690 632 }
633 //
634 return iErr;
635}
636
637//=======================================================================
638//function : PointNearEdge
639//purpose :
640//=======================================================================
641Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
642 (const TopoDS_Edge& aE,
643 const TopoDS_Face& aF,
644 const Standard_Real aT,
645 const Standard_Real theStep,
646 gp_Pnt2d& aPx2DNear,
647 gp_Pnt& aPxNear,
80d55adf 648 const Handle(IntTools_Context)& theContext)
18c06690 649{
650 Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge
651 (aE, aF, aT, theStep, aPx2DNear, aPxNear);
652 if ((iErr != 1) && !theContext->IsPointInOnFace(aF, aPx2DNear)) {
653 gp_Pnt aP;
654 gp_Pnt2d aP2d;
f4ea2ca6 655 //
18c06690 656 iErr = BOPTools_AlgoTools3D::PointInFace
657 (aF, aE, aT, theStep, aP, aP2d, theContext);
658 if (iErr == 0) {
659 aPxNear = aP;
660 aPx2DNear = aP2d;
f4ea2ca6 661 }
18c06690 662 else {
663 iErr = 2; // point is out of the face
4e57c75e 664 }
665 }
18c06690 666 //
667 return iErr;
4e57c75e 668}
4e57c75e 669//=======================================================================
670// function: PointNearEdge
671// purpose:
672//=======================================================================
18c06690 673Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
362dec17 674 (const TopoDS_Edge& aE,
675 const TopoDS_Face& aF,
676 gp_Pnt2d& aPInFace2D,
677 gp_Pnt& aPInFace,
80d55adf 678 const Handle(IntTools_Context)& theContext)
4e57c75e 679{
680 Standard_Real aT, aT1, aT2;
681 //
18c06690 682 // 1. compute parameter on edge
4e57c75e 683 BRep_Tool::Range(aE, aT1, aT2);
684 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
685 //
18c06690 686 // 2. compute point inside the face near the edge
4e57c75e 687 TopoDS_Face aFF=aF;
688 TopoDS_Edge aERight;
689 aFF.Orientation(TopAbs_FORWARD);
690 BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
18c06690 691 //
692 Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge
362dec17 693 (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
18c06690 694 //
695 return iErr;
4e57c75e 696}
4e57c75e 697//=======================================================================
698//function : MinStepIn2d
699//purpose :
700//=======================================================================
362dec17 701Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
4e57c75e 702{
703 Standard_Real dt=1.e-5;
704 return dt;
705}
4e57c75e 706//=======================================================================
707//function : IsEmptyShape
708//purpose :
709//=======================================================================
362dec17 710Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape
711 (const TopoDS_Shape& aS)
4e57c75e 712{
713 Standard_Boolean bHasGeometry=Standard_False;
714 //
1155d05a 715 TopTools_IndexedMapOfShape myShapes;
4e57c75e 716 //
717 Add(aS, myShapes, bHasGeometry);
718
719 return !bHasGeometry;
720}
4e57c75e 721//=======================================================================
722//function : Add
723//purpose :
724//=======================================================================
725void Add(const TopoDS_Shape& aS,
1155d05a 726 TopTools_IndexedMapOfShape& myShapes,
4e57c75e 727 Standard_Boolean& bHasGeometry)
728{
729 Standard_Integer anIndex;
730 //
731 if (bHasGeometry) {
732 return;
733 }
734 //
735 if (aS.IsNull()) {
736 return;
737 }
738 //
b2fedee6 739 const TopoDS_Shape& aSx = aS;
4e57c75e 740 //
741 anIndex=myShapes.FindIndex(aSx);
742 if (!anIndex) {
743 bHasGeometry=HasGeometry (aSx);
744 if (bHasGeometry) {
745 return;
746 }
747 //
748 TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
749 for(; anIt.More(); anIt.Next()) {
750 const TopoDS_Shape& aSy=anIt.Value();
751 Add(aSy, myShapes, bHasGeometry);
752 //
753 if (bHasGeometry) {
754 return;
755 }
756 //
757 myShapes.Add(aSx);
758 }
759 }
760}
4e57c75e 761//=======================================================================
762//function : HasGeometry
763//purpose :
764//=======================================================================
362dec17 765Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
4e57c75e 766{
767 Standard_Boolean bHasGeometry=Standard_True;
768 TopAbs_ShapeEnum aType= aS.ShapeType();
769
770 if (aType == TopAbs_VERTEX) {
362dec17 771 return bHasGeometry;
4e57c75e 772 }
4e57c75e 773 //
774 else if (aType == TopAbs_EDGE) {
775 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
776 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
777
778 while (itrc.More()) {
779 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
780 if (CR->IsCurve3D()) {
781 if (!CR->Curve3D().IsNull()) {
782 return bHasGeometry;
783 }
784 }
785 else if (CR->IsCurveOnSurface()) {
786 return bHasGeometry;
787 }
788 else if (CR->IsRegularity()) {
789 return bHasGeometry;
790 }
791 else if (!CR->Polygon3D().IsNull()) {
792 return bHasGeometry;
793 }
794 else if (CR->IsPolygonOnTriangulation()) {
795 return bHasGeometry;
796 }
797 else if (CR->IsPolygonOnSurface()) {
798 return bHasGeometry;
799 }
800 itrc.Next();
801 }
802 }
803 //
804 else if (aType == TopAbs_FACE) {
805 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
806 if (!TF->Surface().IsNull()) {
807 return bHasGeometry;
808 }
809 Handle(Poly_Triangulation) Tr = TF->Triangulation();
810 if (!Tr.IsNull()) {
811 return bHasGeometry;
812 }
813 }
814
815 return !bHasGeometry;
816}
4e57c75e 817//=======================================================================
818//function : OrientEdgeOnFace
819//purpose :
820//=======================================================================
362dec17 821void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
822 const TopoDS_Face& aF,
823 TopoDS_Edge& aERight)
4e57c75e 824{
825 if (BRep_Tool::IsClosed(aE, aF)) {
826 aERight=aE;
827 aERight.Orientation(aE.Orientation());
828
829 Standard_Integer iFoundCount = 0;
830 TopoDS_Edge anEdge = aE;
831 TopExp_Explorer anExp(aF, TopAbs_EDGE);
832
833 for (; anExp.More(); anExp.Next()) {
834 const TopoDS_Shape& aSS=anExp.Current();
835
836 if (aSS.IsSame(aE)) {
837 anEdge = TopoDS::Edge(aSS);
838 iFoundCount++;
839 }
840 }
841
842 if(iFoundCount == 1) {
843 aERight = anEdge;
844 }
845 return;
846 }
847
848 TopExp_Explorer anExp(aF, TopAbs_EDGE);
849 for (; anExp.More(); anExp.Next()) {
850 const TopoDS_Shape& aSS=anExp.Current();
851 if (aSS.IsSame(aE)) {
852 aERight=aE;
853 aERight.Orientation(aSS.Orientation());
854 return;
855 }
856 }
857 aERight=aE;
858 aERight.Orientation(aE.Orientation());
859}
4e57c75e 860//=======================================================================
861//function : PointInFace
862//purpose :
863//=======================================================================
362dec17 864Standard_Integer BOPTools_AlgoTools3D::PointInFace
18c06690 865 (const TopoDS_Face& theF,
362dec17 866 gp_Pnt& theP,
867 gp_Pnt2d& theP2D,
80d55adf 868 const Handle(IntTools_Context)& theContext)
4e57c75e 869{
18c06690 870 Standard_Integer i, iErr = 1;
871 Standard_Real aUMin, aUMax, aVMin, aVMax, aUx;
872 //
873 theContext->UVBounds(theF, aUMin, aUMax, aVMin, aVMax);
874 //
875 gp_Dir2d aD2D(0. , 1.);
876 aUx = IntTools_Tools::IntermediatePoint(aUMin, aUMax);
877 //
878 for (i = 0; i < 2; ++i) {
879 gp_Pnt2d aP2D(aUx, 0.);
880 Handle(Geom2d_Line) aL2D = new Geom2d_Line (aP2D, aD2D);
881 iErr = BOPTools_AlgoTools3D::PointInFace
882 (theF, aL2D, theP, theP2D, theContext);
883 if (iErr == 0) {
884 // done
885 break;
886 }
887 else {
888 // possible reason - incorrect computation of the 2d box of the face.
889 // try to compute the point with the translated line.
890 aUx = aUMax - (aUx - aUMin);
891 }
892 }
893 //
894 return iErr;
895}
896//=======================================================================
897//function : PointInFace
898//purpose :
899//=======================================================================
900Standard_Integer BOPTools_AlgoTools3D::PointInFace
901 (const TopoDS_Face& theF,
902 const TopoDS_Edge& theE,
903 const Standard_Real theT,
904 const Standard_Real theDt2D,
905 gp_Pnt& theP,
906 gp_Pnt2d& theP2D,
80d55adf 907 const Handle(IntTools_Context)& theContext)
18c06690 908{
909 Standard_Integer iErr;
910 Standard_Real f, l;
4e57c75e 911 Handle(Geom2d_Curve) aC2D;
4e57c75e 912 //
18c06690 913 iErr = 0;
914 aC2D = BRep_Tool::CurveOnSurface (theE, theF, f, l);
915 if (aC2D.IsNull()) {
916 iErr = 5;
917 return iErr;
918 }
4e57c75e 919 //
18c06690 920 gp_Pnt2d aP2D;
921 gp_Vec2d aV2D;
4e57c75e 922 //
18c06690 923 aC2D->D1(theT, aP2D, aV2D);
924 gp_Dir2d aD2Dx(aV2D);
4e57c75e 925 //
18c06690 926 gp_Dir2d aD2D;
927 aD2D.SetCoord (-aD2Dx.Y(), aD2Dx.X());
928 //
929 if (theE.Orientation()==TopAbs_REVERSED){
930 aD2D.Reverse();
51db0179 931 }
18c06690 932 //
933 if (theF.Orientation()==TopAbs_REVERSED) {
934 aD2D.Reverse();
51db0179 935 }
4e57c75e 936 //
18c06690 937 Handle(Geom2d_Line) aL2D = new Geom2d_Line(aP2D, aD2D);
938 Handle(Geom2d_TrimmedCurve) aL2DTrim =
939 new Geom2d_TrimmedCurve(aL2D, 0., Precision::Infinite());
940 //
941 iErr = BOPTools_AlgoTools3D::PointInFace
942 (theF, aL2DTrim, theP, theP2D, theContext, theDt2D);
943 //
944 return iErr;
945}
946//=======================================================================
947//function : PointInFace
948//purpose :
949//=======================================================================
950Standard_Integer BOPTools_AlgoTools3D::PointInFace
951 (const TopoDS_Face& theF,
952 const Handle(Geom2d_Curve)& theL2D,
953 gp_Pnt& theP,
954 gp_Pnt2d& theP2D,
80d55adf 955 const Handle(IntTools_Context)& theContext,
18c06690 956 const Standard_Real theDt2D)
957{
958 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
959 Standard_Integer iErr, aIH, aNbDomains;
960 Standard_Real aVx, aV1, aV2;
961 //
962 Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(theF);
963 //
964 Geom2dAdaptor_Curve aHCur(theL2D);
965 //
966 aHatcher.ClrHatchings();
967 aIH = aHatcher.AddHatching(aHCur);
968 //
969 iErr = 0;
970 for (;;) {
971 aHatcher.Trim();
972 bIsDone = aHatcher.TrimDone(aIH);
873c119f 973 if (!bIsDone) {
18c06690 974 iErr = 1;
975 break;
873c119f 976 }
977 //
18c06690 978 aHatcher.ComputeDomains(aIH);
979 bIsDone = aHatcher.IsDone(aIH);
980 if (!bIsDone) {
981 iErr = 2;
873c119f 982 break;
983 }
18c06690 984 //
985 aNbDomains = aHatcher.NbDomains(aIH);
986 if (aNbDomains == 0) {
987 iErr = 2;
988 break;
873c119f 989 }
18c06690 990 //
991 const HatchGen_Domain& aDomain = aHatcher.Domain (aIH, 1);
992 bHasFirstPoint = aDomain.HasFirstPoint();
4e57c75e 993 if (!bHasFirstPoint) {
18c06690 994 iErr = 3;
995 break;
4e57c75e 996 }
997 //
18c06690 998 bHasSecondPoint = aDomain.HasSecondPoint();
4e57c75e 999 if (!bHasSecondPoint) {
18c06690 1000 iErr = 4;
1001 break;
4e57c75e 1002 }
1003 //
18c06690 1004 aV1 = aDomain.FirstPoint().Parameter();
1005 aV2 = aDomain.SecondPoint().Parameter();
4e57c75e 1006 //
18c06690 1007 aVx = (theDt2D > 0. && (aV2 - aV1) > theDt2D) ? (aV1 + theDt2D) :
1008 IntTools_Tools::IntermediatePoint(aV1, aV2);
4e57c75e 1009 //
18c06690 1010 Handle(Geom_Surface) aS = BRep_Tool::Surface(theF);
1011 //
1012 theL2D->D0(aVx, theP2D);
1013 aS->D0(theP2D.X(), theP2D.Y(), theP);
1014 break;
3ed30348 1015 }
4e57c75e 1016 //
18c06690 1017 aHatcher.RemHatching(aIH);
4e57c75e 1018 return iErr;
1019}