Salome HOME
Merge remote branch 'origin/V7_4_BR'
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_AlgoTools.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File    : GEOMAlgo_AlgoTools.cxx
23 //  Created :
24 //  Author  : Peter KURNEV
25
26 #include <GEOMAlgo_AlgoTools.hxx>
27
28 #include <Basics_OCCTVersion.hxx>
29
30 #include <gp_Pnt.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <gp_Dir2d.hxx>
33 #include <Bnd_Box.hxx>
34
35 #include <Geom2d_Curve.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2d_Line.hxx>
38 #include <Geom2d_TrimmedCurve.hxx>
39
40 #include <Geom2dHatch_Intersector.hxx>
41 #include <Geom2dHatch_Hatcher.hxx>
42
43 #include <Geom2dAdaptor_Curve.hxx>
44 #include <HatchGen_Domain.hxx>
45
46 #include <Geom_Curve.hxx>
47 #include <Geom_Surface.hxx>
48
49 #include <GeomAdaptor_Surface.hxx>
50
51 #include <GeomAPI_ProjectPointOnSurf.hxx>
52 #include <GeomAPI_ProjectPointOnCurve.hxx>
53
54 #include <Poly_Triangulation.hxx>
55
56 #include <TopAbs_Orientation.hxx>
57
58 #include <TopLoc_Location.hxx>
59
60 #include <TopoDS.hxx>
61 #include <TopoDS_Iterator.hxx>
62 #include <TopoDS_Face.hxx>
63 #include <TopoDS_Edge.hxx>
64
65 #include <TopExp_Explorer.hxx>
66
67 #include <BRep_Tool.hxx>
68 #include <BRep_Builder.hxx>
69
70 #include <BRepTools.hxx>
71 #include <BRepBndLib.hxx>
72 #include <BRepMesh_IncrementalMesh.hxx>
73
74 #include <IntTools_Tools.hxx>
75
76 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
77 #include <TopTools_ListOfShape.hxx>
78
79 #include <TopTools_ListIteratorOfListOfShape.hxx>
80 #include <TopTools_IndexedMapOfShape.hxx>
81 #include <TopAbs_ShapeEnum.hxx>
82
83 #include <IntTools_Tools.hxx>
84
85 #include <BOPTools_AlgoTools3D.hxx>
86 #include <BOPTools_AlgoTools2D.hxx>
87
88 #include <GEOMAlgo_PassKeyShape.hxx>
89
90
91 static
92   void GetCount(const TopoDS_Shape& aS,
93                 Standard_Integer& iCnt);
94 static
95   void CopySource(const TopoDS_Shape& aS,
96                   TopTools_IndexedDataMapOfShapeShape& aMapSS,
97                   TopoDS_Shape& aSC);
98
99 //=======================================================================
100 //function : CopyShape
101 //purpose  :
102 //=======================================================================
103 void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS,
104                                    TopoDS_Shape& aSC)
105 {
106   TopTools_IndexedDataMapOfShapeShape aMapSS;
107   //
108   CopySource(aS, aMapSS, aSC);
109 }
110 //=======================================================================
111 //function : CopyShape
112 //purpose  :
113 //=======================================================================
114 void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS,
115                                    TopoDS_Shape& aSC,
116                                    TopTools_IndexedDataMapOfShapeShape& aMapSS)
117 {
118   CopySource(aS, aMapSS, aSC);
119 }
120 //=======================================================================
121 //function : CopySource
122 //purpose  :
123 //=======================================================================
124 void CopySource(const TopoDS_Shape& aS,
125                 TopTools_IndexedDataMapOfShapeShape& aMapSS,
126                 TopoDS_Shape& aSC)
127 {
128   Standard_Boolean bFree;
129   TopAbs_ShapeEnum aT;
130   TopoDS_Iterator aIt;
131   TopoDS_Shape aSF;
132   BRep_Builder BB;
133   //
134   aT=aS.ShapeType();
135   //
136   if (aMapSS.Contains(aS)) {
137     aSC=aMapSS.ChangeFromKey(aS);
138     aSC.Orientation(aS.Orientation());
139     return;
140   }
141   else {
142     aSC=aS.EmptyCopied();
143     aMapSS.Add(aS, aSC);
144   }
145   //
146   bFree=aSC.Free();
147   aSC.Free(Standard_True);
148   aSF=aS;
149   if (aT==TopAbs_EDGE){
150     TopAbs_Orientation aOr;
151     //
152     aOr=aS.Orientation();
153     if(aOr==TopAbs_INTERNAL) {
154       aSF.Orientation(TopAbs_FORWARD);
155     }
156   }
157   aIt.Initialize(aSF);
158   for (; aIt.More();  aIt.Next()) {
159     TopoDS_Shape aSCx;
160     //
161     const TopoDS_Shape& aSx=aIt.Value();
162     //
163     CopySource (aSx, aMapSS, aSCx);
164     //
165     aSCx.Orientation(aSx.Orientation());
166     BB.Add(aSC, aSCx);
167   }
168   aSC.Free(bFree);
169 }
170 //=======================================================================
171 //function : FaceNormal
172 //purpose  : 
173 //=======================================================================
174 void GEOMAlgo_AlgoTools::FaceNormal (const TopoDS_Face& aF,
175                                      const Standard_Real U,
176                                      const Standard_Real V,
177                                      gp_Vec& aN)
178 {
179   gp_Pnt aPnt ;
180   gp_Vec aD1U, aD1V;
181   Handle(Geom_Surface) aSurface;
182
183   aSurface=BRep_Tool::Surface(aF);
184   aSurface->D1 (U, V, aPnt, aD1U, aD1V);
185   aN=aD1U.Crossed(aD1V);
186   aN.Normalize();  
187   if (aF.Orientation() == TopAbs_REVERSED){
188     aN.Reverse();
189   }
190   return;
191 }
192 //=======================================================================
193 //function : BuildPCurveForEdgeOnFace
194 //purpose  :
195 //=======================================================================
196 Standard_Integer GEOMAlgo_AlgoTools::BuildPCurveForEdgeOnFace
197   (const TopoDS_Edge& aEold,
198    const TopoDS_Edge& aEnew,
199    const TopoDS_Face& aF,
200 #if OCC_VERSION_LARGE > 0x06070100
201    const Handle(IntTools_Context)& aCtx
202 #else
203    const Handle(BOPInt_Context)& aCtx
204 #endif
205    )
206 {
207   Standard_Boolean bIsClosed, bUClosed, bHasOld;
208   Standard_Integer iRet, aNbPoints;
209   Standard_Real aTS, aTS1, aTS2, aT, aT1, aT2, aScPr, aTol;
210   Standard_Real aU, aV, aUS1, aVS1, aUS2, aVS2;
211   gp_Pnt aP;
212   gp_Pnt2d aP2DS1, aP2DS2, aP2D;
213   gp_Vec2d aV2DS1, aV2DS2;
214   Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2;
215   Handle(Geom_Surface) aS;
216   TopoDS_Edge aES;
217   //
218   iRet=0;
219   //
220   bHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface(aEnew, aF, aC2D, aT1, aT2, aTol);
221   if (bHasOld) {
222     return iRet;
223   }
224   //
225   BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aEnew, aF);
226   aC2D=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
227   if (aC2D.IsNull()){
228     iRet=1;
229     return iRet;
230   }
231   //
232   bIsClosed=BRep_Tool::IsClosed(aEold, aF);
233   if (!bIsClosed) {
234     return iRet;
235   }
236   //
237   aTol=1.e-7;
238   //
239   // 1. bUClosed - direction of closeness
240   //
241   aES=aEold;
242   aES.Orientation(TopAbs_FORWARD);
243   aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
244   //
245   aES.Orientation(TopAbs_REVERSED);
246   aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
247   //
248   aTS=IntTools_Tools::IntermediatePoint(aTS1, aTS2);
249   //
250   aC2DS1->D1(aTS, aP2DS1, aV2DS1);
251   aC2DS2->D1(aTS, aP2DS2, aV2DS2);
252   //
253   gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
254   gp_Dir2d aD2DS12(aV2DS12);
255   const gp_Dir2d& aD2DX=gp::DX2d();
256   //
257   aScPr=aD2DS12*aD2DX;
258   bUClosed=Standard_True;
259   if (fabs(aScPr) < aTol) {
260     bUClosed=!bUClosed;
261   }
262   //
263   // 2. aP2D - point on curve aC2D, that corresponds to aP2DS1
264   aP2DS1.Coord(aUS1, aVS1);
265   aP2DS2.Coord(aUS2, aVS2);
266   //
267   aS=BRep_Tool::Surface(aF);
268   aS->D0(aUS1, aVS1, aP);
269   //
270   GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
271   //
272   aProjPC.Perform(aP);
273   aNbPoints=aProjPC.NbPoints();
274   if (!aNbPoints) {
275     iRet=2;
276     return iRet;
277   }
278   //
279   aT=aProjPC.LowerDistanceParameter();
280
281   //
282   // 3. Build the second 2D curve
283   Standard_Boolean bRevOrder;
284   gp_Vec2d aV2DT, aV2D;
285   Handle(Geom2d_Curve) aC2Dnew;
286   Handle(Geom2d_TrimmedCurve) aC2DTnew;
287   BRep_Builder aBB;
288   //
289   aC2D->D1(aT, aP2D, aV2D);
290   aP2D.Coord(aU, aV);
291   //
292   aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
293   aC2DTnew = new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
294   //
295   aV2DT=aV2DS12;
296   if (!bUClosed) {    // V Closed
297     if (fabs(aV-aVS2)<aTol) {
298       aV2DT.Reverse();
299     }
300   }
301   else {   // U Closed
302     if (fabs(aU-aUS2)<aTol) {
303       aV2DT.Reverse();
304     }
305   }
306   //
307   aC2DTnew->Translate(aV2DT);
308   //
309   // 4 Order the 2D curves
310   bRevOrder=Standard_False;
311   aScPr=aV2D*aV2DS1;
312   if(aScPr<0.) {
313     bRevOrder=!bRevOrder;
314   }
315   //
316   // 5. Update the edge
317   aTol=BRep_Tool::Tolerance(aEnew);
318   if (!bRevOrder) {
319     aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
320   }
321   else {
322     aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
323   }
324   //
325   return iRet;
326 }
327 //////////////////////////////////////////////////////////////////////////
328 //=======================================================================
329 // function: MakeContainer
330 // purpose:
331 //=======================================================================
332 void GEOMAlgo_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
333                                        TopoDS_Shape& theC)
334 {
335   BRep_Builder aBB;
336   //
337   switch(theType) {
338     case TopAbs_COMPOUND:{
339       TopoDS_Compound aC;
340       aBB.MakeCompound(aC);
341       theC=aC;
342     }
343       break;
344       //
345     case TopAbs_COMPSOLID:{
346       TopoDS_CompSolid aCS;
347       aBB.MakeCompSolid(aCS);
348       theC=aCS;
349     }
350       break;
351       //
352     case TopAbs_SOLID:{
353       TopoDS_Solid aSolid;
354       aBB.MakeSolid(aSolid);
355       theC=aSolid;
356     }
357       break;
358       //
359       //
360     case TopAbs_SHELL:{
361       TopoDS_Shell aShell;
362       aBB.MakeShell(aShell);
363       theC=aShell;
364     }
365       break;
366       //
367     case TopAbs_WIRE: {
368       TopoDS_Wire aWire;
369       aBB.MakeWire(aWire);
370       theC=aWire;
371     }
372       break;
373       //
374     default:
375       break;
376   }
377 }
378 //=======================================================================
379 //function : IsUPeriodic
380 //purpose  :
381 //=======================================================================
382 Standard_Boolean GEOMAlgo_AlgoTools::IsUPeriodic(const  Handle(Geom_Surface) &aS)
383 {
384   Standard_Boolean bRet;
385   GeomAbs_SurfaceType aType;
386   GeomAdaptor_Surface aGAS;
387   //
388   aGAS.Load(aS);
389   aType=aGAS.GetType();
390   bRet=(aType==GeomAbs_Cylinder||
391         aType==GeomAbs_Cone ||
392         aType==GeomAbs_Sphere);
393   //
394   return bRet;
395 }
396
397 //=======================================================================
398 //function : RefinePCurveForEdgeOnFace
399 //purpose  :
400 //=======================================================================
401 void GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE,
402                                                    const TopoDS_Face& aF,
403                                                    const Standard_Real aUMin,
404                                                    const Standard_Real aUMax)
405 {
406   Standard_Real aT1, aT2, aTx, aUx, aTol;
407   gp_Pnt2d aP2D;
408   Handle(Geom_Surface) aS;
409   Handle(Geom2d_Curve) aC2D;
410   BRep_Builder aBB;
411   //
412   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
413   if (!aC2D.IsNull()) {
414     if (BRep_Tool::IsClosed(aE, aF)) {
415       return;
416     }
417     aTx=IntTools_Tools::IntermediatePoint(aT1, aT2);
418     aC2D->D0(aTx, aP2D);
419     aUx=aP2D.X();
420     if (aUx < aUMin || aUx > aUMax) {
421       // need to rebuild
422       Handle(Geom2d_Curve) aC2Dx;
423       //
424       aTol=BRep_Tool::Tolerance(aE);
425       aBB.UpdateEdge(aE, aC2Dx, aF, aTol);
426     }
427   }
428 }
429 //=======================================================================
430 //function :IsSplitToReverse
431 //purpose  : 
432 //=======================================================================
433 Standard_Boolean GEOMAlgo_AlgoTools::IsSplitToReverse
434   (const TopoDS_Edge& aEF1,
435    const TopoDS_Edge& aEF2,
436 #if OCC_VERSION_LARGE > 0x06070100
437    const Handle(IntTools_Context)& aContext
438 #else
439    const Handle(BOPInt_Context)& aContext
440 #endif
441    )
442 {
443   Standard_Boolean aFlag;
444   Standard_Real aT1, aT2, aScPr, a, b;
445   gp_Vec aV1, aV2;
446   gp_Pnt aP;
447   
448   
449   Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b);
450   aT1=IntTools_Tools::IntermediatePoint(a, b);
451   aC1->D0(aT1, aP);
452   aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
453
454   if(!aFlag) {
455     return Standard_False;
456   }
457
458   gp_Dir aDT1(aV1);
459   //
460   aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2);
461   if(!aFlag) {
462     return Standard_False;
463   }
464   //
465   aFlag=BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
466   if(!aFlag) {
467     return Standard_False;
468   }
469
470   gp_Dir aDT2(aV2);
471
472   aScPr=aDT1*aDT2;
473
474   return (aScPr<0.);
475 }
476
477
478 //=======================================================================
479 //function : ProjectPointOnShape
480 //purpose  :
481 //=======================================================================
482 Standard_Boolean GEOMAlgo_AlgoTools::ProjectPointOnShape
483   (const gp_Pnt& aP1,
484    const TopoDS_Shape& aS,
485    gp_Pnt& aP2,
486 #if OCC_VERSION_LARGE > 0x06070100
487    const Handle(IntTools_Context)& aCtx
488 #else
489    const Handle(BOPInt_Context)& aCtx
490 #endif
491    )
492 {
493   Standard_Boolean bIsDone = Standard_False;
494   Standard_Real aT2;
495   TopAbs_ShapeEnum aType;
496   //
497   aType = aS.ShapeType();
498   switch (aType)
499     {
500     case TopAbs_EDGE:
501       {
502         const TopoDS_Edge& aE2 = TopoDS::Edge(aS);
503         //
504         if (BRep_Tool::Degenerated(aE2)) { // jfa
505           return Standard_True;
506         }
507         else {
508           Standard_Real f, l;
509           Handle(Geom_Curve) aC3D = BRep_Tool::Curve (aE2, f, l);
510           if (aC3D.IsNull()) {
511             return Standard_True;
512           }
513           bIsDone = aCtx->ProjectPointOnEdge(aP1, aE2, aT2);
514         }
515         if (!bIsDone) {
516           return bIsDone;
517         }
518         //
519         GEOMAlgo_AlgoTools::PointOnEdge(aE2, aT2, aP2);
520       }
521       break;
522       //
523     case TopAbs_FACE:
524       {
525         const TopoDS_Face& aF2 = TopoDS::Face(aS);
526         GeomAPI_ProjectPointOnSurf& aProj = aCtx->ProjPS(aF2);
527         //
528         aProj.Perform(aP1);
529         bIsDone = aProj.IsDone();
530         if (!bIsDone) {
531           return bIsDone;
532         }
533         //
534         aP2 = aProj.NearestPoint();
535       }
536       break;
537       //
538     default:
539       break; // Err
540     }
541   return bIsDone;
542 }
543
544 //=======================================================================
545 //function : PointOnEdge
546 //purpose  :
547 //=======================================================================
548 void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
549                                      gp_Pnt& aP3D)
550 {
551   Standard_Real aTx, aT1, aT2;
552   //
553   BRep_Tool::Curve(aE, aT1, aT2);
554   aTx=IntTools_Tools::IntermediatePoint(aT1, aT2);
555   GEOMAlgo_AlgoTools::PointOnEdge(aE, aTx, aP3D);
556 }
557 //=======================================================================
558 //function : PointOnEdge
559 //purpose  :
560 //=======================================================================
561 void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
562                                      const Standard_Real aT,
563                                      gp_Pnt& aP3D)
564 {
565   Standard_Real aT1, aT2;
566   Handle(Geom_Curve) aC3D;
567   //
568   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
569   aC3D->D0(aT, aP3D);
570 }
571 //=======================================================================
572 //function : PointOnFace
573 //purpose  :
574 //=======================================================================
575 void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF,
576                                      const Standard_Real aU,
577                                      const Standard_Real aV,
578                                      gp_Pnt& aP3D)
579 {
580   Handle(Geom_Surface) aS;
581   //
582   aS=BRep_Tool::Surface(aF);
583   aS->D0(aU, aV, aP3D);
584 }
585 //=======================================================================
586 //function : PointOnFace
587 //purpose  :
588 //=======================================================================
589 void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF,
590                                      gp_Pnt& aP3D)
591 {
592   Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax;
593   //
594   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
595   //
596   aU=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
597   aV=IntTools_Tools::IntermediatePoint(aVMin, aVMax);
598   //
599   GEOMAlgo_AlgoTools::PointOnFace(aF, aU, aV, aP3D);
600 }
601 //=======================================================================
602 //function : PointOnShape
603 //purpose  :
604 //=======================================================================
605 void GEOMAlgo_AlgoTools::PointOnShape(const TopoDS_Shape& aS,
606                                       gp_Pnt& aP3D)
607 {
608   TopAbs_ShapeEnum aType;
609   //
610   aP3D.SetCoord(99.,99.,99.);
611   aType=aS.ShapeType();
612   switch(aType) {
613     case TopAbs_EDGE: {
614       const TopoDS_Edge& aE=TopoDS::Edge(aS);
615       GEOMAlgo_AlgoTools::PointOnEdge(aE, aP3D);
616       }
617       break;
618       //
619     case TopAbs_FACE: {
620       const TopoDS_Face& aF=TopoDS::Face(aS);
621       GEOMAlgo_AlgoTools::PointOnFace(aF, aP3D);
622       }
623       break;
624       //
625     default:
626       break; // Err
627   }
628 }
629 //=======================================================================
630 //function : FindSDShapes
631 //purpose  :
632 //=======================================================================
633 Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
634   (const TopoDS_Shape& aE1,
635    const TopTools_ListOfShape& aLE,
636    const Standard_Real aTol,
637    TopTools_ListOfShape& aLESD,
638 #if OCC_VERSION_LARGE > 0x06070100
639    const Handle(IntTools_Context)& aCtx
640 #else
641    const Handle(BOPInt_Context)& aCtx
642 #endif
643    )
644 {
645   Standard_Boolean bIsDone;
646   Standard_Real aTol2, aD2;
647   gp_Pnt aP1, aP2;
648   TopTools_ListIteratorOfListOfShape aIt;
649   //
650   aTol2=aTol*aTol;
651   GEOMAlgo_AlgoTools::PointOnShape(aE1, aP1);
652   //
653   aIt.Initialize(aLE);
654   for (; aIt.More(); aIt.Next()) {
655     const TopoDS_Shape& aE2=aIt.Value();
656     if (aE2.IsSame(aE1)) {
657        aLESD.Append(aE2);
658     }
659     else {
660       bIsDone=GEOMAlgo_AlgoTools::ProjectPointOnShape(aP1, aE2, aP2, aCtx);
661       if (!bIsDone) {
662         //return 1;
663         continue; // jfa BUG 20361
664       }
665       aD2=aP1.SquareDistance(aP2);
666       if(aD2<aTol2) {
667         aLESD.Append(aE2);
668       }
669     }
670   }
671   return 0;
672 }
673
674 //=======================================================================
675 //function : FindSDShapes
676 //purpose  :
677 //=======================================================================
678 Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes
679   (const TopTools_ListOfShape& aLE,
680    const Standard_Real aTol,
681    TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
682 #if OCC_VERSION_LARGE > 0x06070100
683    const Handle(IntTools_Context)& aCtx
684 #else
685    const Handle(BOPInt_Context)& aCtx
686 #endif
687    )
688 {
689   Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
690   TopTools_ListOfShape aLESD;
691   TopTools_ListIteratorOfListOfShape aIt, aIt1;
692   TopTools_IndexedMapOfShape aMProcessed;
693   TopAbs_ShapeEnum aType;
694   //
695   aNbE=aLE.Extent();
696   if (!aNbE) {
697     return 3; // Err
698   }
699   if (aNbE==1) {
700     return 0; // Nothing to do
701   }
702   //
703   while(1) {
704     aNbEProcessed=aMProcessed.Extent();
705     if (aNbEProcessed==aNbE) {
706       break;
707     }
708     //
709     aIt.Initialize(aLE);
710     for (; aIt.More(); aIt.Next()) {
711       const TopoDS_Shape& aS=aIt.Value();
712       //
713       if (aMProcessed.Contains(aS)) {
714         continue;
715       }
716       //
717       aType=aS.ShapeType();
718       if (aType==TopAbs_EDGE) {
719         const TopoDS_Edge& aE=TopoDS::Edge(aS);
720         if (BRep_Tool::Degenerated(aE)) {
721           aMProcessed.Add(aE);
722           continue;
723         }
724       }
725       //
726       aLESD.Clear();
727       iErr=GEOMAlgo_AlgoTools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
728       if (iErr) {
729         return 2; // Err
730       }
731       //
732       aNbESD=aLESD.Extent();
733       if (!aNbESD) {
734         return 1; // Err
735       }
736       //
737       aMEE.Add(aS, aLESD);
738       //
739       aIt1.Initialize(aLESD);
740       for (; aIt1.More(); aIt1.Next()) {
741         const TopoDS_Shape& aE1=aIt1.Value();
742         aMProcessed.Add(aE1);
743       }
744     }
745   }
746   return 0;
747 }
748 //=======================================================================
749 //function : RefineSDShapes
750 //purpose  :
751 //=======================================================================
752 Standard_Integer GEOMAlgo_AlgoTools::RefineSDShapes
753   (GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMPKLE,
754    const Standard_Real aTol,
755 #if OCC_VERSION_LARGE > 0x06070100
756    const Handle(IntTools_Context)& aCtx
757 #else
758    const Handle(BOPInt_Context)& aCtx
759 #endif
760    )
761 {
762   Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
763   TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
764   //
765   iErr=1;
766   //
767   aNbE=aMPKLE.Extent();
768   for (i=1; i<=aNbE; ++i) {
769     TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
770     //
771     aMEE.Clear();
772     iErr=GEOMAlgo_AlgoTools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
773     if (iErr) {
774       return iErr;
775     }
776     //
777     aNbEE=aMEE.Extent();
778     if (aNbEE==1) {
779       continue;  // nothing to do
780     }
781     //
782     for (j=1; j<=aNbEE; ++j) {
783       TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
784       //
785       if (j==1) {
786         aLSDE.Clear();
787         aLSDE.Append(aLEE);
788       }
789       else {
790         const TopoDS_Shape& aE1=aLEE.First();
791         aMEToAdd.Add(aE1, aLEE);
792       }
793     }
794   }
795   //
796   aNbToAdd=aMEToAdd.Extent();
797   if (!aNbToAdd) {
798     return aNbToAdd;
799   }
800   //
801   for (i=1; i<=aNbToAdd; ++i) {
802     GEOMAlgo_PassKeyShape aPKE1;
803     //
804     const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
805     const TopTools_ListOfShape& aLE=aMEToAdd(i);
806     //
807     aPKE1.SetShapes(aE1);
808     aMPKLE.Add(aPKE1, aLE);
809   }
810   //
811   return 0;
812 }
813 //=======================================================================
814 //function : BuildTriangulation
815 //purpose  :
816 //=======================================================================
817 Standard_Boolean 
818   GEOMAlgo_AlgoTools::BuildTriangulation (const TopoDS_Shape& theShape)
819 {
820   // calculate deflection
821   Standard_Real aDeviationCoefficient = 0.001;
822
823   Bnd_Box B;
824   BRepBndLib::Add(theShape, B);
825   Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
826   B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
827
828   Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
829   Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
830   Standard_Real aHLRAngle = 0.349066;
831
832   // build triangulation
833   BRepMesh_IncrementalMesh Inc (theShape, aDeflection, Standard_False, aHLRAngle);
834
835   // check triangulation
836   bool isTriangulation = true;
837
838   TopExp_Explorer exp (theShape, TopAbs_FACE);
839   if (exp.More())
840   {
841     TopLoc_Location aTopLoc;
842     Handle(Poly_Triangulation) aTRF;
843     aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
844     if (aTRF.IsNull()) {
845       isTriangulation = false;
846     }
847   }
848   else // no faces, try edges
849   {
850     TopExp_Explorer expe (theShape, TopAbs_EDGE);
851     if (!expe.More()) {
852       isTriangulation = false;
853     }
854     else {
855       TopLoc_Location aLoc;
856       Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
857       if (aPE.IsNull()) {
858         isTriangulation = false;
859       }
860     }
861   }
862   return isTriangulation;
863 }
864
865 //=======================================================================
866 //function : IsCompositeShape
867 //purpose  :
868 //=======================================================================
869 Standard_Boolean GEOMAlgo_AlgoTools::IsCompositeShape(const TopoDS_Shape& aS)
870 {
871   Standard_Boolean bRet;
872   Standard_Integer iCnt;
873   TopoDS_Iterator aIt;
874   //
875   iCnt=0;
876   GetCount(aS, iCnt);
877   bRet=(iCnt>1);
878   //
879   return bRet;
880 }
881 //=======================================================================
882 //function : GetCount
883 //purpose  :
884 //=======================================================================
885 void GetCount(const TopoDS_Shape& aS,
886               Standard_Integer& iCnt)
887 {
888   TopoDS_Iterator aIt;
889   TopAbs_ShapeEnum aTS;
890   //
891   aTS=aS.ShapeType();
892   //
893   if (aTS==TopAbs_SHAPE) {
894     return;
895   }
896   if (aTS!=TopAbs_COMPOUND) {
897     ++iCnt;
898     return;
899   }
900   //
901   aIt.Initialize(aS);
902   for (; aIt.More(); aIt.Next()) {
903     const TopoDS_Shape& aSx=aIt.Value();
904     GetCount(aSx, iCnt);
905   }
906 }
907 //=======================================================================
908 //function : PntInFace
909 //purpose  :
910 //=======================================================================
911 Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF,
912                                                gp_Pnt& theP,
913                                                gp_Pnt2d& theP2D)
914 {
915   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
916   Standard_Integer iErr, aIx, aNbDomains, i;
917   Standard_Real aUMin, aUMax, aVMin, aVMax;
918   Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
919   Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
920   gp_Dir2d aD2D (0., 1.);
921   gp_Pnt2d aP2D;
922   gp_Pnt aPx;
923   Handle(Geom2d_Curve) aC2D;
924   Handle(Geom2d_TrimmedCurve) aCT2D;
925   Handle(Geom2d_Line) aL2D;
926   Handle(Geom_Surface) aS;
927   TopAbs_Orientation aOrE;
928   TopoDS_Face aFF;
929   TopExp_Explorer aExp;
930   //
931   aTolHatch2D=1.e-8;
932   aTolHatch3D=1.e-8;
933   aTotArcIntr=1.e-10;
934   aTolTangfIntr=1.e-10;
935   //
936   Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
937   Geom2dHatch_Hatcher aHatcher(aIntr,
938                                aTolHatch2D, aTolHatch3D,
939                                Standard_True, Standard_False);
940   //
941   iErr=0;
942   aEpsT=1.e-12;
943   //
944   aFF=aF;
945   aFF.Orientation (TopAbs_FORWARD);
946   //
947   aS=BRep_Tool::Surface(aFF);
948   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
949   //
950   // 1
951   aExp.Init (aFF, TopAbs_EDGE);
952   for (; aExp.More() ; aExp.Next()) {
953     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
954     aOrE=aE.Orientation();
955     //
956     aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
957     if (aC2D.IsNull() ) {
958       iErr=1;
959       return iErr;
960     }
961     if (fabs(aU1-aU2) < aEpsT) {
962       iErr=2;
963       return iErr;
964     }
965     //
966     aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
967     aHatcher.AddElement(aCT2D, aOrE);
968   }// for (; aExp.More() ; aExp.Next()) {
969   //
970   // 2
971   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
972   aP2D.SetCoord(aUx, 0.);
973   aL2D=new Geom2d_Line (aP2D, aD2D);
974   Geom2dAdaptor_Curve aHCur(aL2D);
975   //
976   aIx=aHatcher.AddHatching(aHCur) ;
977   //
978   // 3.
979   aHatcher.Trim();
980   bIsDone=aHatcher.TrimDone(aIx);
981   if (!bIsDone) {
982     iErr=3;
983     return iErr;
984   }
985   //
986   aHatcher.ComputeDomains(aIx);
987   bIsDone=aHatcher.IsDone(aIx);
988   if (!bIsDone) {
989     iErr=4;
990     return iErr;
991   }
992   //
993   // 4.
994   aNbDomains=aHatcher.NbDomains(aIx);
995   for (i=1; i<=aNbDomains; ++i) {
996     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
997     bHasFirstPoint=aDomain.HasFirstPoint();
998     if (!bHasFirstPoint) {
999       iErr=5;
1000       return iErr;
1001     }
1002     //
1003     aV1=aDomain.FirstPoint().Parameter();
1004     //
1005     bHasSecondPoint=aDomain.HasSecondPoint();
1006     if (!bHasSecondPoint) {
1007       iErr=6;
1008       return iErr;
1009     }
1010     //
1011     aV2=aDomain.SecondPoint().Parameter();
1012     //
1013     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
1014     //
1015     break;
1016   }
1017   //
1018   aS->D0(aUx, aVx, aPx);
1019   //
1020   theP2D.SetCoord(aUx, aVx);
1021   theP=aPx;
1022   //
1023   return iErr;
1024 }