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