0024106: Project non-regression test: geom/boolean_operations6/G3 provides incorrect...
[occt.git] / src / BOPTools / BOPTools_AlgoTools3D.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19#include <BOPTools_AlgoTools3D.ixx>
20
21#include <TopExp.hxx>
22#include <TopExp_Explorer.hxx>
23
24#include <TopoDS.hxx>
25#include <TopoDS_Shape.hxx>
26#include <TopoDS_Edge.hxx>
27#include <TopoDS_Face.hxx>
28#include <TopoDS_Vertex.hxx>
29
30#include <BOPCol_IndexedMapOfShape.hxx>
31#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
32
33#include <BRep_Builder.hxx>
34#include <BRep_Tool.hxx>
35#include <BRepTools.hxx>
36#include <BRepAdaptor_Surface.hxx>
37
38#include <gp_Vec2d.hxx>
39#include <gp_Pnt2d.hxx>
40#include <gp_Lin2d.hxx>
41#include <gp_Dir2d.hxx>
42#include <gp_Vec.hxx>
43#include <gp_Dir.hxx>
44#include <gp_Pln.hxx>
45
46#include <Geom2d_Curve.hxx>
47#include <Geom2d_TrimmedCurve.hxx>
48#include <Geom2d_Line.hxx>
49
50#include <Geom_Curve.hxx>
51#include <Geom_Surface.hxx>
52#include <Geom_BSplineSurface.hxx>
53#include <Geom_BezierSurface.hxx>
54
55#include <GeomAdaptor_Surface.hxx>
56
57#include <IntTools_Tools.hxx>
58
59#include <BOPTools_AlgoTools2D.hxx>
60
61#include <GProp_GProps.hxx>
62#include <BRepGProp.hxx>
63#include <BRepBndLib.hxx>
64#include <Bnd_Box.hxx>
65#include <gp_Cylinder.hxx>
66#include <BRep_TVertex.hxx>
67#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
68#include <BRep_PointRepresentation.hxx>
69#include <BRep_TEdge.hxx>
70#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
71#include <BRep_CurveRepresentation.hxx>
72#include <BRep_TFace.hxx>
73#include <Poly_Triangulation.hxx>
74#include <BRep_Builder.hxx>
75#include <BOPInt_Context.hxx>
76#include <Geom2dAdaptor_Curve.hxx>
77#include <Geom2dHatch_Hatcher.hxx>
78#include <HatchGen_Domain.hxx>
79
80static void Add(const TopoDS_Shape& aS,
81 BOPCol_IndexedMapOfShape& myShapes,
82 Standard_Boolean& bHasGeometry);
83static
84 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
85
86//=======================================================================
87//function : DoSplitSEAMOnFace
88//purpose :
89//=======================================================================
90 void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
fe343049 91 const TopoDS_Face& aF)
4e57c75e 92{
fe343049 93 Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
94 Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU=1.e-7, anU1,
95 anV, dV=1.e-7, anV1;
4e57c75e 96 Standard_Real aScPr;
97 gp_Pnt2d aP2D;
98 gp_Vec2d aVec2D;
99 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
100 Handle(Geom2d_Curve) C2D1;
101 Handle(Geom2d_Line) aLD1;
102 Handle(Geom_Surface) aS;
103 BRep_Builder BB;
104 TopoDS_Edge aSp;
105 //
106 aSp=aSplit;
107 aSp.Orientation(TopAbs_FORWARD);
4e57c75e 108 aTol=BRep_Tool::Tolerance(aSp);
fe343049 109 //
4e57c75e 110 aS=BRep_Tool::Surface(aF);
111 bIsUPeriodic=aS->IsUPeriodic();
fe343049 112 bIsVPeriodic=aS->IsVPeriodic();
113 //
114 anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
115 anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
116 //
117 if (!bIsUPeriodic && !bIsVPeriodic) {
118 Standard_Boolean bIsUClosed, bIsVClosed;
4e57c75e 119 Standard_Real aUmin, aUmax, aVmin, aVmax;
120 Handle(Geom_BSplineSurface) aBS;
121 Handle(Geom_BezierSurface) aBZ;
122 //
123 bIsUClosed=Standard_False;
fe343049 124 bIsVClosed=Standard_False;
4e57c75e 125 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
126 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
127 //
128 if (!aBS.IsNull()) {
129 bIsUClosed=aBS->IsUClosed();
fe343049 130 bIsVClosed=aBS->IsVClosed();
4e57c75e 131 aBS->Bounds(aUmin, aUmax, aVmin, aVmax);
132 }
133 else if (!aBZ.IsNull()) {
134 bIsUClosed=aBZ->IsUClosed();
fe343049 135 bIsVClosed=aBZ->IsVClosed();
4e57c75e 136 aBZ->Bounds(aUmin, aUmax, aVmin, aVmax);
137 }
fe343049 138 if (!bIsUClosed && !bIsVClosed) {
4e57c75e 139 return;
140 }
141 //
fe343049 142 if (bIsUClosed) {
143 anUPeriod=aUmax-aUmin;
144 }
145 if (bIsVClosed) {
146 anVPeriod=aVmax-aVmin;
147 }
4e57c75e 148 }
149 //
150 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
151 //
152 aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
153 C2D1->D1(aT, aP2D, aVec2D);
fe343049 154 gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
4e57c75e 155 //
fe343049 156 anU=aP2D.X();
157 anV=aP2D.Y();
4e57c75e 158 //
fe343049 159 anU1=anU;
160 anV1=anV;
4e57c75e 161 //
fe343049 162 if (anUPeriod > 0.){
163 if (fabs (anU) < dU) {
164 bIsLeft=Standard_True;
165 anU1=anU+anUPeriod;
166 }
167 else if (fabs (anU-anUPeriod) < dU) {
168 bIsLeft=Standard_False;
169 anU1=anU-anUPeriod;
170 }
4e57c75e 171 }
fe343049 172 //
173 if (anVPeriod > 0.) {
174 if (fabs (anV) < dV) {
175 bIsLeft=Standard_True;
176 anV1=anV+anVPeriod;
177 }
178 else if (fabs (anV-anVPeriod) < dV) {
179 bIsLeft=Standard_False;
180 anV1=anV-anVPeriod;
181 }
4e57c75e 182 }
fe343049 183 //
184 if (anU1==anU && anV1==anV) {
4e57c75e 185 return;
186 }
187 //
fe343049 188 aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
189 //
4e57c75e 190 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
191 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b);
fe343049 192 //
4e57c75e 193 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
194 Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b);
fe343049 195 gp_Vec2d aTrV(anU1-anU, anV1-anV);
4e57c75e 196 aC2->Translate(aTrV);
197 //
198 if (!bIsLeft) {
199 if (aScPr<0.) {
200 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
201 }
202 else {
203 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
204 }
205 }
206 else {
207 if (aScPr<0.) {
208 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
209 }
210 else {
211 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
212 }
213 }
4e57c75e 214}
215
216//=======================================================================
217//function : GetNormalToFaceOnEdge
218//purpose :
219//=======================================================================
220 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
221 const TopoDS_Face& aF,
222 gp_Dir& aDNF)
223{
224 Standard_Real aT, aT1, aT2;
225
226 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
227 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
228
229 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
230
231 if (aF.Orientation()==TopAbs_REVERSED){
232 aDNF.Reverse();
233 }
234}
235
236//=======================================================================
237//function : GetNormalToFaceOnEdge
238//purpose :
239//=======================================================================
240 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
241 const TopoDS_Face& aF1,
242 const Standard_Real aT,
243 gp_Dir& aDNF1)
244{
245 Standard_Real U, V, aTolPC;
246 gp_Pnt2d aP2D;
247 gp_Pnt aP;
248 gp_Vec aD1U, aD1V;
249
250 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
251
252 Handle(Geom2d_Curve)aC2D1;
253 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC);
254
255 aC2D1->D0(aT, aP2D);
256 U=aP2D.X();
257 V=aP2D.Y();
258
259 aS1->D1(U, V, aP, aD1U, aD1V);
260 gp_Dir aDD1U(aD1U);
261 gp_Dir aDD1V(aD1V);
262
263 aDNF1=aDD1U^aDD1V;
264}
265
266//=======================================================================
267//function : SenseFlag
268//purpose :
269//=======================================================================
270 Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
271 const gp_Dir& aDNF2)
272{
273 Standard_Boolean bIsDirsCoinside;
274 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
275 if (!bIsDirsCoinside) {
276 return 0;
277 }
278
279 Standard_Real aScPr;
280
281 aScPr=aDNF1*aDNF2;
282 if (aScPr<0.) {
283 return -1;
284 }
285 else if (aScPr>0.) {
286 return 1;
287 }
288 return -1;
289}
290
291//=======================================================================
292//function : GetNormalToSurface
293//purpose :
294//=======================================================================
295 Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface (const Handle(Geom_Surface)& aS,
296 const Standard_Real U,
297 const Standard_Real V,
298 gp_Dir& aDNS)
299{
300 Standard_Boolean bFlag;
301
302 gp_Pnt aP;
303 gp_Vec aD1U, aD1V;
304
305 aS->D1(U, V, aP, aD1U, aD1V);
306
307 gp_Dir aDD1U(aD1U);
308 gp_Dir aDD1V(aD1V);
309
310 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
311 if (!bFlag) {
312 return bFlag;
313 }
314
315 aDNS=aDD1U^aDD1V;
316 return bFlag;
317}
318
319//=======================================================================
320//function : GetApproxNormalToFaceOnEdge
321//purpose :
322//=======================================================================
323
324 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(const TopoDS_Edge& aE,
325 const TopoDS_Face& aF,
326 const Standard_Real aT,
327 gp_Pnt& aPNear,
328 gp_Dir& aDNF,
329 Standard_Real aDt2D)
330{
331 Standard_Real aFirst, aLast;
332 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
333
334 if (aC2D.IsNull()) {
335 return;
336 }
337 gp_Pnt2d aPx2DNear;
338 PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
339 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
340
341 BOPTools_AlgoTools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
342
343 if (aF.Orientation()==TopAbs_REVERSED){
344 aDNF.Reverse();
345 }
346}
347
348
349//=======================================================================
350//function : GetApproxNormalToFaceOnEdge
351//purpose :
352//=======================================================================
353 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE,
354 const TopoDS_Face& aF,
355 const Standard_Real aT,
356 gp_Pnt& aPNear,
357 gp_Dir& aDNF,
358 Handle(BOPInt_Context)& theContext)
359{
360 Standard_Real aFirst, aLast;
361 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
362
363 if (aC2D.IsNull()) {
364 return;
365 }
366 //gp_Pnt aPNear;
367 gp_Pnt2d aPx2DNear;
368 BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, aPx2DNear, aPNear, theContext);
369
370 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
371
372 BOPTools_AlgoTools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
373
374 if (aF.Orientation()==TopAbs_REVERSED){
375 aDNF.Reverse();
376 }
377}
378
379//=======================================================================
380//function : PointNearEdge
381//purpose :
382//=======================================================================
383 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
384 const TopoDS_Face& aF,
385 const Standard_Real aT,
386 const Standard_Real aDt2D,
387 gp_Pnt2d& aPx2DNear,
388 gp_Pnt& aPxNear)
389{
390 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
391 GeomAbs_SurfaceType aTS;
392 Handle(Geom2d_Curve) aC2D;
393 Handle(Geom_Surface) aS;
394 //
395 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
396 if (aC2D.IsNull()) {
397 aPx2DNear.SetCoord (99., 99);
398 return;
399 }
400 //
401 aS=BRep_Tool::Surface(aF);
402 //
403 gp_Pnt2d aPx2D;
404 gp_Vec2d aVx2D;
405 aC2D->D1 (aT, aPx2D, aVx2D);
406 gp_Dir2d aDx2D(aVx2D);
407
408 gp_Dir2d aDP;
409 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
410
411 if (aE.Orientation()==TopAbs_REVERSED){
412 aDP.Reverse();
413 }
414
415 if (aF.Orientation()==TopAbs_REVERSED) {
416 aDP.Reverse();
417 }
418 //
419 aETol = BRep_Tool::Tolerance(aE);
420 aFTol = BRep_Tool::Tolerance(aF);
f4ea2ca6 421 // NPAL19220
4e57c75e 422 GeomAdaptor_Surface aGAS(aS);
423 aTS=aGAS.GetType();
424 if (aTS==GeomAbs_BSplineSurface) {
425 if (aETol > 1.e-5) {
426 aFTol=aETol;
427 }
428 }
429 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
430 //if( aETol > 1.e-5 && aFTol > 1.e-5 ) {
431 //pkv/103/D7
432 if(aTS!=GeomAbs_Sphere) {
433 gp_Vec2d transVec( aDP );
434 transVal = aDt2D + aETol + aFTol;
435 if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
436 Standard_Real aR, dT;
437 //
438 gp_Cylinder aCyl=aGAS.Cylinder();
439 aR=aCyl.Radius();
440 dT=1.-transVal/aR;
441 if (dT>=-1 && dT<=1) {
442 dT=acos(dT);
443 transVal=dT;
444 }
445 }
446 //
447 transVec.Multiply(transVal);
448 aPx2DNear = aPx2D.Translated( transVec );
449 }
450 else {
451 aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
452 }
453 }
454 else {
455 aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
456 }
457 //
458 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
459}
460
461//=======================================================================
462//function : PointNearEdge
463//purpose :
464//=======================================================================
f4ea2ca6 465void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
466 const TopoDS_Face& aF,
467 const Standard_Real aT,
468 gp_Pnt2d& aPx2DNear,
469 gp_Pnt& aPxNear,
470 Handle(BOPInt_Context)& theContext)
4e57c75e 471{
f4ea2ca6 472 Standard_Real aTolE, aTolF, dTx, dT2D;
473 Handle(Geom_Surface) aS;
474 GeomAdaptor_Surface aGAS;
4e57c75e 475 //
f4ea2ca6 476 dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
477 //
478 aS = BRep_Tool::Surface(aF);
479 aGAS.Load(aS);
4e57c75e 480 if (aGAS.GetType()==GeomAbs_Cylinder ||
481 aGAS.GetType()==GeomAbs_Sphere) {
f4ea2ca6 482 dT2D=10.*dT2D;
483 }
484 //
4e57c75e 485 aTolE = BRep_Tool::Tolerance(aE);
486 aTolF = BRep_Tool::Tolerance(aF);
f4ea2ca6 487 dTx = 2.*(aTolE + aTolF);
488 if (dTx > dT2D) {
489 dT2D=dTx;
490 }
491 //
492 BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
4e57c75e 493 if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
f4ea2ca6 494 Standard_Integer iErr;
495 Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
4e57c75e 496 gp_Pnt aP;
497 gp_Pnt2d aP2d;
4e57c75e 498 //
f4ea2ca6 499 BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
500 //
501 dU=aU2-aU1;
502 dV=aV2-aV1;
503 //
504 dTresh=1.e-4;
505 if (dT2D > dTresh) {
506 dTresh=dT2D;
507 }
508 //
509 if (dU < dTresh || dV < dTresh) {
510 iErr = BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2d, theContext);
4e57c75e 511 if (!iErr) {
512 aPxNear = aP;
513 aPx2DNear = aP2d;
514 }
515 }
516 }
517}
518
519//=======================================================================
520// function: PointNearEdge
521// purpose:
522//=======================================================================
523 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
524 const TopoDS_Face& aF,
525 gp_Pnt2d& aPInFace2D,
526 gp_Pnt& aPInFace,
527 Handle(BOPInt_Context)& theContext)
528{
529 Standard_Real aT, aT1, aT2;
530 //
531 // 1.
532 BRep_Tool::Range(aE, aT1, aT2);
533 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
534 //
535 // 2. a Point inside Face near aPOnEdge aPInFace;
536 TopoDS_Face aFF=aF;
537 TopoDS_Edge aERight;
538 aFF.Orientation(TopAbs_FORWARD);
539 BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
540
541 BOPTools_AlgoTools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
542}
543
544//=======================================================================
545//function : MinStepIn2d
546//purpose :
547//=======================================================================
548 Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
549{
550 Standard_Real dt=1.e-5;
551 return dt;
552}
553
554//=======================================================================
555//function : IsEmptyShape
556//purpose :
557//=======================================================================
558 Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape(const TopoDS_Shape& aS)
559{
560 Standard_Boolean bHasGeometry=Standard_False;
561 //
562 BOPCol_IndexedMapOfShape myShapes;
563 //
564 Add(aS, myShapes, bHasGeometry);
565
566 return !bHasGeometry;
567}
568
569//=======================================================================
570//function : Add
571//purpose :
572//=======================================================================
573void Add(const TopoDS_Shape& aS,
574 BOPCol_IndexedMapOfShape& myShapes,
575 Standard_Boolean& bHasGeometry)
576{
577 Standard_Integer anIndex;
578 //
579 if (bHasGeometry) {
580 return;
581 }
582 //
583 if (aS.IsNull()) {
584 return;
585 }
586 //
587 TopoDS_Shape aSx = aS;
588 //
589 anIndex=myShapes.FindIndex(aSx);
590 if (!anIndex) {
591 bHasGeometry=HasGeometry (aSx);
592 if (bHasGeometry) {
593 return;
594 }
595 //
596 TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
597 for(; anIt.More(); anIt.Next()) {
598 const TopoDS_Shape& aSy=anIt.Value();
599 Add(aSy, myShapes, bHasGeometry);
600 //
601 if (bHasGeometry) {
602 return;
603 }
604 //
605 myShapes.Add(aSx);
606 }
607 }
608}
609
610//=======================================================================
611//function : HasGeometry
612//purpose :
613//=======================================================================
614 Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
615{
616 Standard_Boolean bHasGeometry=Standard_True;
617 TopAbs_ShapeEnum aType= aS.ShapeType();
618
619 if (aType == TopAbs_VERTEX) {
620
621 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(aS.TShape());
622 BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points());
623
624 while (itrp.More()) {
625 const Handle(BRep_PointRepresentation)& PR = itrp.Value();
626
627 if (PR->IsPointOnCurve()) {
628 return bHasGeometry;
629 }
630
631 else if (PR->IsPointOnCurveOnSurface()) {
632 return bHasGeometry;
633 }
634
635 else if (PR->IsPointOnSurface()) {
636 return bHasGeometry;
637 }
638 itrp.Next();
639 }
640 }
641
642 //
643 else if (aType == TopAbs_EDGE) {
644 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
645 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
646
647 while (itrc.More()) {
648 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
649 if (CR->IsCurve3D()) {
650 if (!CR->Curve3D().IsNull()) {
651 return bHasGeometry;
652 }
653 }
654 else if (CR->IsCurveOnSurface()) {
655 return bHasGeometry;
656 }
657 else if (CR->IsRegularity()) {
658 return bHasGeometry;
659 }
660 else if (!CR->Polygon3D().IsNull()) {
661 return bHasGeometry;
662 }
663 else if (CR->IsPolygonOnTriangulation()) {
664 return bHasGeometry;
665 }
666 else if (CR->IsPolygonOnSurface()) {
667 return bHasGeometry;
668 }
669 itrc.Next();
670 }
671 }
672 //
673 else if (aType == TopAbs_FACE) {
674 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
675 if (!TF->Surface().IsNull()) {
676 return bHasGeometry;
677 }
678 Handle(Poly_Triangulation) Tr = TF->Triangulation();
679 if (!Tr.IsNull()) {
680 return bHasGeometry;
681 }
682 }
683
684 return !bHasGeometry;
685}
686
687
688//=======================================================================
689//function : OrientEdgeOnFace
690//purpose :
691//=======================================================================
692 void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
693 const TopoDS_Face& aF,
694 TopoDS_Edge& aERight)
695{
696 if (BRep_Tool::IsClosed(aE, aF)) {
697 aERight=aE;
698 aERight.Orientation(aE.Orientation());
699
700 Standard_Integer iFoundCount = 0;
701 TopoDS_Edge anEdge = aE;
702 TopExp_Explorer anExp(aF, TopAbs_EDGE);
703
704 for (; anExp.More(); anExp.Next()) {
705 const TopoDS_Shape& aSS=anExp.Current();
706
707 if (aSS.IsSame(aE)) {
708 anEdge = TopoDS::Edge(aSS);
709 iFoundCount++;
710 }
711 }
712
713 if(iFoundCount == 1) {
714 aERight = anEdge;
715 }
716 return;
717 }
718
719 TopExp_Explorer anExp(aF, TopAbs_EDGE);
720 for (; anExp.More(); anExp.Next()) {
721 const TopoDS_Shape& aSS=anExp.Current();
722 if (aSS.IsSame(aE)) {
723 aERight=aE;
724 aERight.Orientation(aSS.Orientation());
725 return;
726 }
727 }
728 aERight=aE;
729 aERight.Orientation(aE.Orientation());
730}
731
732//=======================================================================
733//function : PointInFace
734//purpose :
735//=======================================================================
736 Standard_Integer BOPTools_AlgoTools3D::PointInFace(const TopoDS_Face& aF,
737 gp_Pnt& theP,
738 gp_Pnt2d& theP2D,
739 Handle(BOPInt_Context)& theContext)
740{
741 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
742 Standard_Integer iErr, aIx, aNbDomains, i;
743 Standard_Real aUMin, aUMax, aVMin, aVMax;
744 Standard_Real aVx, aUx, aV1, aV2, aEpsT;
745 gp_Dir2d aD2D (0., 1.);
746 gp_Pnt2d aP2D;
747 gp_Pnt aPx;
748 Handle(Geom2d_Curve) aC2D;
749 Handle(Geom2d_Line) aL2D;
750 Handle(Geom_Surface) aS;
751 TopoDS_Face aFF;
752 //
753 Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
754 //
755 iErr=0;
756 aEpsT=1.e-12;
757 //
758 aFF=aF;
759 aFF.Orientation (TopAbs_FORWARD);
760 //
761 aS=BRep_Tool::Surface(aFF);
762 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
763 //
764 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
765 aP2D.SetCoord(aUx, 0.);
766 aL2D=new Geom2d_Line (aP2D, aD2D);
767 Geom2dAdaptor_Curve aHCur(aL2D);
768 //
769 aIx=aHatcher.AddHatching(aHCur) ;
770 //
771 aHatcher.Trim();
772 bIsDone=aHatcher.TrimDone(aIx);
773 if (!bIsDone) {
774 iErr=1;
775 return iErr;
776 }
777 //
778 aHatcher.ComputeDomains(aIx);
779 bIsDone=aHatcher.IsDone(aIx);
780 if (!bIsDone) {
781 iErr=2;
782 return iErr;
783 }
784 //
785 aNbDomains=aHatcher.NbDomains(aIx);
786 for (i=1; i<=aNbDomains; ++i) {
787 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
788 bHasFirstPoint=aDomain.HasFirstPoint();
789 if (!bHasFirstPoint) {
790 iErr=3;
791 return iErr;
792 }
793 //
794 aV1=aDomain.FirstPoint().Parameter();
795 //
796 bHasSecondPoint=aDomain.HasSecondPoint();
797 if (!bHasSecondPoint) {
798 iErr=4;
799 return iErr;
800 }
801 //
802 aV2=aDomain.SecondPoint().Parameter();
803 //
804 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
805 //
806 break;
807 }
808 //
809 aS->D0(aUx, aVx, aPx);
810 //
811 theP2D.SetCoord(aUx, aVx);
812 theP=aPx;
813 //
814 return iErr;
815}