Salome HOME
Copyrights update
[modules/geom.git] / src / NMTTools / NMTTools_Tools.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20 // File:        NMTTools_Tools.cxx
21 // Created:     Mon Dec  8 10:35:15 2003
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25
26 #include <NMTTools_Tools.ixx>
27
28 #include <TColStd_IndexedMapOfInteger.hxx>
29
30 #include <gp_Pnt.hxx>
31 #include <gp_XYZ.hxx>
32 #include <gp_Pnt2d.hxx>
33
34 #include <Geom_Surface.hxx>
35 #include <GeomAPI_ProjectPointOnSurf.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Edge.hxx>
41
42 #include <TopExp.hxx>
43
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_IndexedMapOfShape.hxx>
46
47 #include <BRep_Tool.hxx>
48 #include <BRep_Builder.hxx>
49 #include <BRepTools.hxx>
50
51 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
52 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
53
54 #include <BOPTools_VVInterference.hxx>
55 #include <BOPTools_SSInterference.hxx>
56
57 #include <BOPTools_Tools2D.hxx>
58 #include <BOPTools_Tools.hxx>
59 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
60 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
61 #include <NMTTools_CoupleOfShape.hxx>
62 #include <TopTools_IndexedMapOfShape.hxx>
63 #include <Geom2d_Curve.hxx>
64 #include <Geom_Curve.hxx>
65 #include <Geom_TrimmedCurve.hxx>
66 #include <BOPTools_Tools2D.hxx>
67 #include <BRepLib.hxx>
68 #include <BOPTools_Tools3D.hxx>
69 #include <TopExp_Explorer.hxx>
70
71 static 
72   void ProcessBlock(const Standard_Integer iV,
73                     const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
74                     TColStd_IndexedMapOfInteger& aProcessed,
75                     TColStd_IndexedMapOfInteger& aChain);
76 static
77   void ProcessBlock(const TopoDS_Shape& aF,
78                     const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
79                     TopTools_IndexedMapOfShape& aProcessed,
80                     TopTools_IndexedMapOfShape& aChain);
81
82 //=======================================================================
83 // function: MakePCurve
84 // purpose: 
85 //=======================================================================
86   void  NMTTools_Tools::MakePCurve(const TopoDS_Edge& aE,
87                                    const TopoDS_Face& aF,
88                                    const Handle(Geom2d_Curve)& aC2Dx,
89                                    const Standard_Real aTolR2D)
90 {
91   Standard_Integer k, aNbV;   
92   Standard_Real aTolEdge, aTolFact, aTolV, aTolVmax;
93   Standard_Real aTFirst, aTLast, aOutFirst, aOutLast, aOutTol;
94   TopoDS_Face aFFWD;
95   TopTools_IndexedMapOfShape aVMap;
96   BRep_Builder aBB;
97   //
98   aFFWD=aF;
99   aFFWD.Orientation(TopAbs_FORWARD);
100   //
101   aTolEdge=BRep_Tool::Tolerance(aE);
102   aTolFact=Max(aTolEdge, aTolR2D);
103   //
104   TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap);
105   //
106   aTolVmax=-1.;
107   aNbV=aVMap.Extent();
108   for (k=1; k<=aNbV; ++k) {
109     const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k));
110     aTolV=BRep_Tool::Tolerance(aV);
111     if (aTolV>aTolVmax) {
112       aTolVmax=aTolV;
113     }
114   }
115   //
116   if (aTolFact>aTolVmax) {
117     aTolFact=aTolVmax;
118   }
119   //
120   const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aTFirst, aTLast);
121   Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aTFirst, aTLast);
122   //
123   Handle(Geom2d_Curve) aC2D, aC2DA;
124   //
125   aC2D=aC2Dx;
126   if (aC2D.IsNull()) {
127     BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
128     BOPTools_Tools2D::CurveOnSurface(aE, aFFWD, aC2D, aOutFirst, aOutLast, aOutTol, Standard_True);
129   }
130   if (aC3DE->IsPeriodic()) {
131     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aTFirst, aTLast,  aC2D, aC2DA); 
132   }
133   else {
134     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA); 
135   }
136   //
137   aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolFact);
138   BRepLib::SameParameter(aE);
139 }
140   
141 //=======================================================================
142 // function: IsSplitInOnFace
143 // purpose: 
144 //=======================================================================
145   Standard_Boolean NMTTools_Tools::IsSplitInOnFace(const TopoDS_Edge& aE,
146                                                    const TopoDS_Face& aF,
147                                                    IntTools_Context& aContext)
148 {
149   Standard_Boolean bFlag;
150   Standard_Real aT, aTolE, aTolF, aTol, aDist, aU, aV;
151   gp_Pnt aP;
152   gp_Pnt2d aP2D;
153   //
154   aTolE=BRep_Tool::Tolerance(aE);
155   aTolF=BRep_Tool::Tolerance(aF);
156   aTol=aTolE+aTolF;
157   //
158   GeomAPI_ProjectPointOnSurf& aProjector=aContext.ProjPS(aF);
159   //
160   aT=BOPTools_Tools2D::IntermediatePoint(aE);
161   BOPTools_Tools::PointOnEdge(aE, aT, aP);
162   //
163   aProjector.Perform(aP);
164   bFlag=aProjector.IsDone();
165   if (!bFlag) {
166     return bFlag;
167   }
168   //
169   aDist=aProjector.LowerDistance();
170   bFlag=(aDist <= aTol);
171   if (!bFlag) {
172     return bFlag;
173   }
174   //
175   aProjector.LowerDistanceParameters(aU, aV);
176   aP2D.SetCoord(aU, aV);
177   bFlag=aContext.IsPointInOnFace (aF, aP2D);
178   return bFlag;
179 }
180 //=======================================================================
181 // function: NMTTools_Tools::MakeNewVertex
182 // purpose : 
183 //=======================================================================
184   void NMTTools_Tools::MakeNewVertex(const TopTools_ListOfShape& aLVs,
185                                      TopoDS_Vertex& aNewVertex)
186 {
187   Standard_Integer aNb;
188   Standard_Real aTi, aDi, aDmax=-1.e5;
189   gp_Pnt aPi, aP;
190   gp_XYZ aXYZ(0.,0.,0.), aXYZi;
191   TopTools_ListIteratorOfListOfShape anIt;
192   //
193   aNb=aLVs.Extent();
194   if (!aNb) {
195     return;
196   }
197   //
198   anIt.Initialize(aLVs);
199   for (; anIt.More(); anIt.Next()) {
200     TopoDS_Vertex aVi=TopoDS::Vertex(anIt.Value());
201     aPi=BRep_Tool::Pnt(aVi);
202     aXYZi=aPi.XYZ();
203     aXYZ=aXYZ+aXYZi;
204   }
205   //
206   aXYZ.Divide((Standard_Real)aNb);
207   aP.SetXYZ(aXYZ);
208   //
209   anIt.Initialize(aLVs);
210   for (; anIt.More(); anIt.Next()) {
211     TopoDS_Vertex aVi=TopoDS::Vertex(anIt.Value());
212     aPi=BRep_Tool::Pnt(aVi);
213     aTi=BRep_Tool::Tolerance(aVi);
214     aDi=aP.Distance(aPi);
215     aDi=aDi+aTi;
216     if (aDi > aDmax) {
217       aDmax=aDi;
218     }
219   }
220   BRep_Builder aBB;
221   aBB.MakeVertex (aNewVertex, aP, aDmax);
222 }
223 //=======================================================================
224 // function: FindChains
225 // purpose : 
226 //=======================================================================
227   void NMTTools_Tools::FindChains(const BOPTools_CArray1OfSSInterference& FFs,
228                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
229 {
230   Standard_Boolean bIsTangentFaces;
231   Standard_Integer j, aNb, anIndex1, anIndex2;
232   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMCV;
233   //
234   aNb=FFs.Extent();
235   for (j=1; j<=aNb; ++j) {
236     const BOPTools_SSInterference& aFF=FFs(j);
237     //
238     bIsTangentFaces=aFF.IsTangentFaces();
239     if (!bIsTangentFaces) {
240       continue;
241     }
242     //
243     aFF.Indices(anIndex1, anIndex2);
244     //
245     if (aMCV.Contains(anIndex1)) {
246       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex1);
247       aMV.Add(anIndex1);
248       aMV.Add(anIndex2);
249     }
250     else {
251       TColStd_IndexedMapOfInteger aMV;
252       aMV.Add(anIndex1);
253       aMV.Add(anIndex2);
254       aMCV.Add(anIndex1, aMV);
255     }
256     //
257     if (aMCV.Contains(anIndex2)) {
258       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex2);
259       aMV.Add(anIndex1);
260       aMV.Add(anIndex2);
261     }
262     else {
263       TColStd_IndexedMapOfInteger aMV;
264       aMV.Add(anIndex1);
265       aMV.Add(anIndex2);
266       aMCV.Add(anIndex2, aMV);
267     }
268   }
269   NMTTools_Tools::FindChains(aMCV, aMapChains);
270 }
271 //=======================================================================
272 // function: FindChains
273 // purpose : 
274 //=======================================================================
275   void NMTTools_Tools::FindChains(const BOPTools_CArray1OfVVInterference& VVs,
276                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
277 {
278   Standard_Integer j, aNb, anIndex1, anIndex2;
279   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMCV;
280   //
281   aNb=VVs.Extent();
282   for (j=1; j<=aNb; ++j) {
283     const BOPTools_VVInterference& VV=VVs(j);
284     VV.Indices(anIndex1, anIndex2);
285     //
286     if (aMCV.Contains(anIndex1)) {
287       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex1);
288       aMV.Add(anIndex1);
289       aMV.Add(anIndex2);
290     }
291     else {
292       TColStd_IndexedMapOfInteger aMV;
293       aMV.Add(anIndex1);
294       aMV.Add(anIndex2);
295       aMCV.Add(anIndex1, aMV);
296     }
297     //
298     if (aMCV.Contains(anIndex2)) {
299       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex2);
300       aMV.Add(anIndex1);
301       aMV.Add(anIndex2);
302     }
303     else {
304       TColStd_IndexedMapOfInteger aMV;
305       aMV.Add(anIndex1);
306       aMV.Add(anIndex2);
307       aMCV.Add(anIndex2, aMV);
308     }
309   }
310   NMTTools_Tools::FindChains(aMCV, aMapChains);
311 }
312
313 //=======================================================================
314 // function: FindChains
315 // purpose : 
316 //=======================================================================
317   void NMTTools_Tools::FindChains(const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
318                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
319 {
320   Standard_Integer  i, j, aNbCV, aNbV, iV, iVx;
321   TColStd_IndexedMapOfInteger aProcessed, aChain;
322   //
323   aNbCV=aMCV.Extent();
324   for (i=1; i<=aNbCV; ++i) {
325     iV=aMCV.FindKey(i);
326     if (aProcessed.Contains(iV)) {
327       continue;
328     }
329     //
330     aProcessed.Add(iV);
331     aChain.Add(iV);
332     //
333     const TColStd_IndexedMapOfInteger& aMV=aMCV(i);
334     aNbV=aMV.Extent();
335     for (j=1; j<=aNbV; ++j) {
336       iVx=aMV(j);
337       ProcessBlock(iVx, aMCV, aProcessed, aChain);
338     }
339     aMapChains.Add(i, aChain);
340     aChain.Clear();
341   }
342 }
343 //=======================================================================
344 // function: ProcessBlock
345 // purpose: 
346 //=======================================================================
347 void ProcessBlock(const Standard_Integer iV,
348                   const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
349                   TColStd_IndexedMapOfInteger& aProcessed,
350                   TColStd_IndexedMapOfInteger& aChain)
351 {
352   Standard_Integer j, aNbV, iVx;
353   //
354   if (aProcessed.Contains(iV)) {
355     return;
356   }
357   aProcessed.Add(iV);
358   aChain.Add(iV);
359   //
360   const TColStd_IndexedMapOfInteger& aMV=aMCV.FindFromKey(iV);
361   aNbV=aMV.Extent();
362   for (j=1; j<=aNbV; ++j) {
363     iVx=aMV(j);
364     ProcessBlock(iVx, aMCV, aProcessed, aChain);
365   }
366 }
367 //=======================================================================
368 // function: AreFacesSameDomain
369 // purpose : 
370 //=======================================================================
371   Standard_Boolean NMTTools_Tools::AreFacesSameDomain(const TopoDS_Face& aF1x,
372                                                       const TopoDS_Face& aF2y,
373                                                       IntTools_Context& aCtx)
374 {
375   Standard_Boolean bFlag;
376   Standard_Integer i, aNbE1, aNbE2;
377   
378   TopTools_IndexedMapOfShape aME1, aME2;
379   TopoDS_Edge aEF1, aEF2;
380   TopoDS_Face aF1, aF2;
381   //
382   aF1=aF1x;
383   aF1.Orientation(TopAbs_FORWARD);
384   aF2=aF2y;
385   aF2.Orientation(TopAbs_FORWARD);
386   //
387   TopExp::MapShapes(aF1, TopAbs_EDGE, aME1);
388   TopExp::MapShapes(aF2, TopAbs_EDGE, aME2);
389   //
390   bFlag=Standard_False;
391   //
392   aNbE1=aME1.Extent();
393   aNbE2=aME2.Extent();
394   //
395   if(!aNbE1 || !aNbE2){
396     return bFlag;
397   }
398   //
399   if(aNbE1!=aNbE2) {
400     return bFlag;
401   }
402   //
403   for (i=1; i<=aNbE1; ++i) {
404     const TopoDS_Edge& aE1=TopoDS::Edge(aME1(i));
405     if (BRep_Tool::Degenerated(aE1)) {
406       // not try to compare deg edges because it 
407       // can not have same TShape on different faces at all
408       continue; 
409     }
410     if (!aME2.Contains(aE1)) {
411       return bFlag;
412     }
413   }
414   //
415   Standard_Real aTolF1, aTolF2, aTol;
416   gp_Pnt2d aP2D;
417   gp_Pnt aP;
418   TopExp_Explorer anExp;
419   //
420   aTolF1=BRep_Tool::Tolerance(aF1);
421   aTolF2=BRep_Tool::Tolerance(aF2);
422   aTol=aTolF1+aTolF2;
423   //
424   anExp.Init(aF1, TopAbs_EDGE);
425   for (; anExp.More(); anExp.Next()) {
426     const TopoDS_Edge& aE1=TopoDS::Edge(anExp.Current());
427     if (!BRep_Tool::Degenerated(aE1)) {
428       BOPTools_Tools3D::PointNearEdge(aE1, aF1, aP2D, aP);
429       bFlag=aCtx.IsValidPointForFace(aP, aF2, aTol);
430       break;
431     }
432   }
433   return bFlag;
434   /*
435   //
436   Standard_Real aU1, aU2, aV1, aV2;
437   Standard_Real dU, dV, aU, aV;
438   Standard_Integer aNbP=5, aNbP1, j;
439   gp_Pnt2d aP2D;
440   gp_Pnt aP;
441   //
442   aTolF1=BRep_Tool::Tolerance(aF1);
443   aTolF2=BRep_Tool::Tolerance(aF2);
444   aTol=aTolF1+aTolF2;
445   //
446   BRepTools::UVBounds(aF1, aU1, aU2, aV1, aV2);
447   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
448   //
449   aNbP1=aNbP+1;
450   dU=(aU2-aU1)/aNbP1;
451   dV=(aV2-aV1)/aNbP1;
452   //
453   for (i=1; i<=aNbP; ++i) {
454     aU=aU1+i*dU;
455     for (j=1; j<=aNbP; ++j) {
456       aV=aV1+j*dV;
457       aP2D.SetCoord(aU, aV);
458       //
459       if(aCtx.IsPointInFace(aF1, aP2D)) {
460         aP=aS1->Value(aU, aV);
461         bFlag=aCtx.IsValidPointForFace(aP, aF2, aTol);
462         if (!bFlag) {
463           return bFlag;
464         }
465       }
466     }
467   }
468   */
469   //
470   return bFlag;
471 }
472 //=======================================================================
473 // function: FindChains
474 // purpose : 
475 //=======================================================================
476   void NMTTools_Tools::FindChains(const NMTTools_ListOfCoupleOfShape& aLCS,
477                                   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains)
478 {
479   NMTTools_ListIteratorOfListOfCoupleOfShape aItCS; 
480   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMCV;
481   //
482   aItCS.Initialize(aLCS);
483   for (; aItCS.More(); aItCS.Next()) {
484     const NMTTools_CoupleOfShape& aCS=aItCS.Value();
485     //
486     const TopoDS_Shape& aF1=aCS.Shape1();
487     const TopoDS_Shape& aF2=aCS.Shape2();
488     //
489     //
490     if (aMCV.Contains(aF1)) {
491       TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF1);
492       aMV.Add(aF1);
493       aMV.Add(aF2);
494     }
495     else {
496       TopTools_IndexedMapOfShape aMV;
497       aMV.Add(aF1);
498       aMV.Add(aF2);
499       aMCV.Add(aF1, aMV);
500     }
501     //
502     if (aMCV.Contains(aF2)) {
503       TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF2);
504       aMV.Add(aF1);
505       aMV.Add(aF2);
506     }
507     else {
508       TopTools_IndexedMapOfShape aMV;
509       aMV.Add(aF1);
510       aMV.Add(aF2);
511       aMCV.Add(aF2, aMV);
512     }
513   }
514   NMTTools_Tools::FindChains(aMCV, aMapChains);
515 }
516 //=======================================================================
517 // function: FindChains
518 // purpose : 
519 //=======================================================================
520   void NMTTools_Tools::FindChains(const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
521                                   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains)
522 {
523   Standard_Integer  i, j, aNbCV, aNbV;
524   TopTools_IndexedMapOfShape aProcessed, aChain;
525   //
526   aNbCV=aMCV.Extent();
527   for (i=1; i<=aNbCV; ++i) {
528     const TopoDS_Shape& aF=aMCV.FindKey(i);
529     if (aProcessed.Contains(aF)) {
530       continue;
531     }
532     //
533     aProcessed.Add(aF);
534     aChain.Add(aF);
535     //
536     const TopTools_IndexedMapOfShape& aMV=aMCV(i);
537     aNbV=aMV.Extent();
538     for (j=1; j<=aNbV; ++j) {
539       const TopoDS_Shape& aFx=aMV(j);
540       ProcessBlock(aFx, aMCV, aProcessed, aChain);
541     }
542     aMapChains.Add(aF, aChain);
543     aChain.Clear();
544   }
545 }
546 //=======================================================================
547 // function: ProcessBlock
548 // purpose: 
549 //=======================================================================
550 void ProcessBlock(const TopoDS_Shape& aF,
551                   const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
552                   TopTools_IndexedMapOfShape& aProcessed,
553                   TopTools_IndexedMapOfShape& aChain)
554 {
555   Standard_Integer j, aNbV;
556   //
557   if (aProcessed.Contains(aF)) {
558     return;
559   }
560   aProcessed.Add(aF);
561   aChain.Add(aF);
562   //
563   const TopTools_IndexedMapOfShape& aMV=aMCV.FindFromKey(aF);
564   aNbV=aMV.Extent();
565   for (j=1; j<=aNbV; ++j) {
566     const TopoDS_Shape& aFx=aMV(j);
567     ProcessBlock(aFx, aMCV, aProcessed, aChain);
568   }
569 }