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