Salome HOME
Merging with WPdev
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_FinderShapeOn2.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/ or email : webmaster.salome@opencascade.com
19 //
20 // File:        GEOMAlgo_FinderShapeOn1.cxx
21 // Created:     Fri Mar  4 10:31:06 2005
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25
26 #include <GEOMAlgo_FinderShapeOn2.ixx>
27 #include <math.h>
28
29
30 #include <Precision.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <TColStd_MapOfInteger.hxx>
33
34 #include <gp_Trsf.hxx>
35 #include <gp_Cylinder.hxx>
36 #include <gp_Pnt.hxx>
37
38 #include <TColgp_Array1OfPnt.hxx>
39
40 #include <Poly_Array1OfTriangle.hxx>
41 #include <Poly_Triangle.hxx>
42 #include <Poly_PolygonOnTriangulation.hxx>
43 #include <Poly_Triangulation.hxx>
44
45 #include <Geom_Curve.hxx>
46 #include <Geom_Surface.hxx>
47 #include <GeomAdaptor_Surface.hxx>
48 #include <GeomAbs_SurfaceType.hxx>
49 #include <GeomAdaptor_Curve.hxx>
50 #include <GeomAbs_CurveType.hxx>
51
52 #include <TopAbs_State.hxx>
53
54 #include <TopLoc_Location.hxx>
55 #include <TopoDS.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Vertex.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <TopoDS_Edge.hxx>
60
61 #include <TopExp.hxx>
62 #include <TopExp_Explorer.hxx>
63
64 #include <TopTools_IndexedMapOfShape.hxx>
65
66 #include <BRep_Tool.hxx>
67 #include <BRepLib_MakeEdge.hxx>
68
69 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
70
71 #include <GEOMAlgo_SurfaceTools.hxx>
72 #include <GEOMAlgo_StateCollector.hxx>
73
74 #include <GEOMAlgo_PassKey.hxx>
75 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
76 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
77
78 //=======================================================================
79 //function : GEOMAlgo_FinderShapeOn1
80 //purpose  : 
81 //=======================================================================
82   GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
83 :
84   GEOMAlgo_ShapeAlgo()
85 {
86   myTolerance=0.0001;
87   myShapeType=TopAbs_VERTEX;
88   myState=GEOMAlgo_ST_UNKNOWN;
89   myNbPntsMin=3;
90   myNbPntsMax=0;
91 }
92 //=======================================================================
93 //function : ~
94 //purpose  : 
95 //=======================================================================
96   GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
97 {
98 }
99 //=======================================================================
100 //function : SetClsf
101 //purpose  : 
102 //=======================================================================
103   void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
104 {
105   myClsf=aClsf;
106 }
107 //=======================================================================
108 //function : Clsf
109 //purpose  : 
110 //=======================================================================
111   const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
112 {
113   return myClsf;
114 }
115 //=======================================================================
116 //function : SetShapeType
117 //purpose  : 
118 //=======================================================================
119   void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
120 {
121   myShapeType=aType;
122 }
123 //=======================================================================
124 //function : ShapeType
125 //purpose  : 
126 //=======================================================================
127   TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
128 {
129   return myShapeType;
130 }
131 //=======================================================================
132 //function : SetState
133 //purpose  : 
134 //=======================================================================
135   void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
136 {
137   myState=aState;
138 }
139 //=======================================================================
140 //function : State
141 //purpose  : 
142 //=======================================================================
143   GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
144 {
145   return myState;
146 }
147 //=======================================================================
148 //function : SetNbPntsMin
149 //purpose  : 
150 //=======================================================================
151   void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
152 {
153   myNbPntsMin=aNb;
154 }
155 //=======================================================================
156 //function : NbPntsMin
157 //purpose  : 
158 //=======================================================================
159   Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
160 {
161   return myNbPntsMin;
162 }
163 //=======================================================================
164 //function : SetNbPntsMax
165 //purpose  : 
166 //=======================================================================
167   void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
168 {
169   myNbPntsMax=aNb;
170 }
171 //=======================================================================
172 //function : NbPntsMax
173 //purpose  : 
174 //=======================================================================
175   Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
176 {
177   return myNbPntsMax;
178 }
179 //=======================================================================
180 // function: MSS
181 // purpose: 
182 //=======================================================================
183   const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
184 {
185   return myMSS;
186 }
187 //=======================================================================
188 // function: Shapes
189 // purpose: 
190 //=======================================================================
191   const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
192 {
193   Standard_Integer i, aNb;
194   TopTools_ListOfShape* pL;
195   //
196   pL=(TopTools_ListOfShape*) &myLS;
197   pL->Clear();
198   //
199   aNb=myMSS.Extent();
200   for (i=1; i<=aNb; ++i) {
201     const TopoDS_Shape& aS=myMSS.FindKey(i);
202     if (aS.ShapeType()==myShapeType) {
203       pL->Append(aS);
204     }
205   }
206   return myLS;
207 }
208 //=======================================================================
209 //function : Perform
210 //purpose  : 
211 //=======================================================================
212   void GEOMAlgo_FinderShapeOn2::Perform()
213 {
214   myErrorStatus=0;
215   myWarningStatus=0;
216   myLS.Clear();
217   myMSS.Clear();
218   //
219   CheckData();
220   if(myErrorStatus) {
221     return;
222   }
223   //
224   myClsf->SetTolerance(myTolerance);
225   //
226   // 1
227   ProcessVertices();
228   if(myErrorStatus) {
229     return;
230   }
231   if (myShapeType==TopAbs_VERTEX) {
232     return;
233   }
234   //
235   // 2
236   ProcessEdges();
237   if(myErrorStatus) {
238     return;
239   }
240   if (myShapeType==TopAbs_EDGE) {
241     return;
242   }
243   //
244   // 3
245   ProcessFaces();
246   if(myErrorStatus) {
247     return;
248   }
249   if (myShapeType==TopAbs_FACE) {
250     return;
251   }
252   //
253   // 4
254   ProcessSolids(); 
255   //
256 }
257 //=======================================================================
258 //function : CheckData
259 //purpose  : 
260 //=======================================================================
261   void GEOMAlgo_FinderShapeOn2::CheckData()
262 {
263   Standard_Integer iErr;
264   //
265   myErrorStatus=0;
266   //
267   if(myClsf.IsNull()) {
268     myErrorStatus=10; // myClsf=NULL
269     return;
270   }
271   //
272   myClsf->CheckData();
273   iErr=myClsf->ErrorStatus();
274   if (iErr) {
275     myErrorStatus=41; // invalid data for classifier
276     return;
277   }
278   //
279   if (myShape.IsNull()) {
280     myErrorStatus=11; // myShape=NULL
281     return;
282   }
283   //
284   if (!(myShapeType==TopAbs_VERTEX ||
285         myShapeType==TopAbs_EDGE ||
286         myShapeType==TopAbs_FACE ||
287         myShapeType==TopAbs_SOLID)) {
288     myErrorStatus=12; // unallowed subshape type
289     return;
290   }
291   //
292   if (myState==GEOMAlgo_ST_UNKNOWN || 
293       myState==GEOMAlgo_ST_INOUT) {
294     myErrorStatus=13; // unallowed state type
295     return;
296   }
297 }
298 //=======================================================================
299 //function : ProcessVertices
300 //purpose  : 
301 //=======================================================================
302   void GEOMAlgo_FinderShapeOn2::ProcessVertices()
303 {
304   myErrorStatus=0;
305   //
306   Standard_Boolean bIsConformState;
307   Standard_Integer i, aNb, iErr;
308   gp_Pnt aP;
309   TopTools_IndexedMapOfShape aM;
310   TopAbs_State aSt;
311   //
312   TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
313   aNb=aM.Extent();
314   for (i=1; i<=aNb; ++i) {
315     const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
316     aP=BRep_Tool::Pnt(aV);
317     //
318     myClsf->SetPnt(aP);
319     myClsf->Perform();
320     iErr=myClsf->ErrorStatus();
321     if (iErr) {
322       myErrorStatus=40; // point can not be classified
323       return;
324     }
325     //
326     aSt=myClsf->State();
327     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
328     //
329     if (myShapeType==TopAbs_VERTEX){
330       if (bIsConformState) {
331         myMSS.Add(aV, aSt);
332       }
333     }
334     else if (bIsConformState || aSt==TopAbs_ON) {
335       myMSS.Add(aV, aSt);
336     }
337   }
338 }
339 //=======================================================================
340 //function : ProcessEdges
341 //purpose  : 
342 //=======================================================================
343   void GEOMAlgo_FinderShapeOn2::ProcessEdges()
344 {
345   myErrorStatus=0;
346   //
347   Standard_Boolean bIsConformState, bIsToBreak;
348   Standard_Integer i, aNb, iCnt, iErr;
349   TopAbs_State aSt;
350   TopTools_IndexedMapOfShape aM;
351   TopExp_Explorer aExp;
352   GEOMAlgo_ListIteratorOfListOfPnt aIt;
353   //
354   TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
355   aNb=aM.Extent();
356   for (i=1; i<=aNb; ++i) {
357     GEOMAlgo_ListOfPnt aLP;
358     GEOMAlgo_StateCollector aSC;
359     //
360     const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
361     //
362     aExp.Init(aE, TopAbs_VERTEX);
363     for (; aExp.More(); aExp.Next()) {
364       const TopoDS_Shape& aV=aExp.Current();
365       //
366       bIsConformState=myMSS.Contains(aV);
367       if (!bIsConformState) {
368         break;// vertex has non-conformed state
369       }
370       else {
371         aSt=myMSS.FindFromKey(aV);
372         aSC.AppendState(aSt);
373       }
374     }
375     //
376     if (!bIsConformState) {
377       continue; // vertex has non-conformed state,skip edge
378     }
379     //
380     if (BRep_Tool::Degenerated(aE)) {
381       myMSS.Add(aE, aSt); 
382       continue;
383     }
384     //
385     if (myState==GEOMAlgo_ST_ON) {
386       Standard_Boolean bCanBeON;
387       Standard_Real aT1, aT2;
388       Handle(Geom_Curve) aC; 
389       //
390       aC=BRep_Tool::Curve(aE, aT1, aT2);
391       bCanBeON=myClsf->CanBeON(aC);
392       if(!bCanBeON) {
393         continue;
394       }
395     }
396     //
397     InnerPoints(aE, aLP);
398     if (myErrorStatus) {
399       return;  
400     }
401     //
402     bIsConformState=Standard_True;
403     aIt.Initialize(aLP);
404     for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
405       if (myNbPntsMax) {
406         if (iCnt > myNbPntsMax) {
407           break;
408         }
409       }
410       //
411       const gp_Pnt& aP=aIt.Value();
412       //
413       myClsf->SetPnt(aP);
414       myClsf->Perform();
415       iErr=myClsf->ErrorStatus();
416       if (iErr) {
417         myErrorStatus=40; // point can not be classified
418         return;
419       }
420       //
421       aSt=myClsf->State();
422       //
423       bIsToBreak=aSC.AppendState(aSt);
424       if (bIsToBreak) {
425         break;
426       }
427     }
428     //
429     aSt=aSC.State();    
430     //
431     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
432     if (myShapeType==TopAbs_EDGE) {
433       if (bIsConformState) {
434         myMSS.Add(aE, aSt);
435       }
436     }
437     else if (bIsConformState || aSt==TopAbs_ON) {
438       myMSS.Add(aE, aSt);
439     }
440   } //  for (i=1; i<=aNb; ++i) next edge 
441 }
442 //=======================================================================
443 //function : ProcessFaces
444 //purpose  : 
445 //=======================================================================
446   void GEOMAlgo_FinderShapeOn2::ProcessFaces()
447 {
448   myErrorStatus=0;
449   //
450   Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
451   Standard_Integer i, aNbF, iCnt, iErr;
452   TopAbs_State aSt;
453   TopTools_IndexedMapOfShape aM;
454   TopExp_Explorer aExp;
455   GEOMAlgo_ListIteratorOfListOfPnt aIt;
456   //
457   TopExp::MapShapes(myShape, TopAbs_FACE, aM);
458   aNbF=aM.Extent();
459   for (i=1; i<=aNbF; ++i) {
460     GEOMAlgo_StateCollector aSC;
461     GEOMAlgo_ListOfPnt aLP;
462     //
463     const TopoDS_Face& aF=TopoDS::Face(aM(i));
464     //
465     if (myState==GEOMAlgo_ST_ON) {
466       Handle(Geom_Surface) aS;
467       //
468       aS=BRep_Tool::Surface(aF);
469       bCanBeON=myClsf->CanBeON(aS);
470       if(!bCanBeON) {
471         continue;
472       }
473     }
474     //
475     aExp.Init(aF, TopAbs_EDGE);
476     for (; aExp.More(); aExp.Next()) {
477       const TopoDS_Shape& aE=aExp.Current();
478       bIsConformState=myMSS.Contains(aE);
479       if (!bIsConformState) {
480         break;// edge has non-conformed state
481       }
482       else {
483         aSt=myMSS.FindFromKey(aE);
484         aSC.AppendState(aSt);
485       }
486     }
487     //
488     if (!bIsConformState) {
489       continue; // edge has non-conformed state,skip face
490     }
491     //
492     InnerPoints(aF, aLP);
493     if (myErrorStatus) {
494       return;
495     }
496     //
497     bIsConformState=Standard_True;
498     aIt.Initialize(aLP);
499     for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
500       if (myNbPntsMax) {
501         if (iCnt > myNbPntsMax) {
502           break;
503         }
504       }
505       //
506       const gp_Pnt& aP=aIt.Value();
507       //
508       myClsf->SetPnt(aP);
509       myClsf->Perform();
510       iErr=myClsf->ErrorStatus();
511       if (iErr) {
512         myErrorStatus=40; // point can not be classified
513         return;
514       }
515       //
516       aSt=myClsf->State();
517       //
518       bIsToBreak=aSC.AppendState(aSt);
519       if (bIsToBreak) {
520         break;
521       }
522     }
523     //
524     aSt=aSC.State();    
525     //
526     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
527     if (myShapeType==TopAbs_FACE) {
528       if (bIsConformState) {
529         myMSS.Add(aF, aSt);
530       }
531     }
532     else if (bIsConformState || aSt==TopAbs_ON) {
533       myMSS.Add(aF, aSt);
534     }
535   }//  for (i=1; i<=aNb; ++i) next face 
536 }
537 //=======================================================================
538 //function : ProcessSolids
539 //purpose  : 
540 //=======================================================================
541   void GEOMAlgo_FinderShapeOn2::ProcessSolids()
542 {
543   myErrorStatus=0;
544   //
545   Standard_Boolean bIsConformState;
546   Standard_Integer i, aNbS, j, aNbF;
547   TopTools_IndexedMapOfShape aM, aMF;
548   TopAbs_State aSt;
549   //
550   TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
551   aNbS=aM.Extent();
552   for (i=1; i<=aNbS; ++i) {
553     GEOMAlgo_StateCollector aSC;
554     //
555     const TopoDS_Shape& aSd=aM(i);
556     aMF.Clear();
557     TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
558     aNbF=aMF.Extent();
559     for (j=1; j<=aNbF; ++j) {
560       const TopoDS_Shape& aF=aMF(j);
561       bIsConformState=myMSS.Contains(aF);
562       if (!bIsConformState) {
563         break;// face has non-conformed state
564       }
565       else {
566         aSt=myMSS.FindFromKey(aF);
567         aSC.AppendState(aSt);
568       }
569     }
570     //
571     if (!bIsConformState) {
572       continue; // face has non-conformed state,skip solid
573     }
574     //
575     aSt=aSC.State();    
576     //
577     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
578     if (bIsConformState) {
579       myMSS.Add(aSd, aSt);
580     }
581   }
582 }
583 //
584 //=======================================================================
585 //function : InnerPoints
586 //purpose  : 
587 //=======================================================================
588   void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
589                                           GEOMAlgo_ListOfPnt& aLP)
590 {
591   myErrorStatus=0;
592   //
593   Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
594   TopLoc_Location aLoc;
595   Handle(Poly_Triangulation) aTRF;
596   TColStd_MapOfInteger aMBN;
597   GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
598   GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
599   gp_Pnt aP, aP1, aP2;
600   //
601   aLP.Clear();
602   //
603   aTRF=BRep_Tool::Triangulation(aF, aLoc);
604   if (aTRF.IsNull()) {
605     myErrorStatus=20; // no triangulation found
606     return;  
607   }
608   //
609   const gp_Trsf& aTrsf=aLoc.Transformation();
610   const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
611   const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
612   //
613   // map link/nbtriangles
614   j1=aTrs.Lower();
615   j2=aTrs.Upper();
616   for (j=j1; j<=j2; ++j) {
617     const Poly_Triangle& aTr=aTrs(j);
618     aTr.Get(n[0], n[1], n[2]);
619     n[3]=n[0];
620     for (k=0; k<3; ++k) {
621       GEOMAlgo_PassKey aPK;
622       //
623       aPK.SetIds(n[k], n[k+1]);
624       if (aMPKI.IsBound(aPK)) {
625         Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
626         ++iCntX;
627       }
628       else {
629         aMPKI.Bind(aPK, 1);
630       }
631     }
632   }
633   //
634   // boundary nodes aMBN
635   aNbLinks=aMPKI.Extent();
636   aIt.Initialize(aMPKI);
637   for (; aIt.More(); aIt.Next()) {
638     iCnt=aIt.Value();
639     if (iCnt==1) {
640       const GEOMAlgo_PassKey& aPK=aIt.Key();
641       //qf
642       /*
643       aNbMax=aPK.NbMax();
644       pIds=(Standard_Integer*)aPK.Key();
645       for (k=1; k<3; ++k) {
646         aNx=*(pIds+aNbMax-k);
647         aMBN.Add(aNx);
648       }
649       */
650       aNx=(Standard_Integer)aPK.Id(1);
651       aMBN.Add(aNx);
652       aNx=(Standard_Integer)aPK.Id(2);
653       aMBN.Add(aNx);
654       //qt
655     }
656   }
657   //
658   // inner nodes=all_nodes - boundary_nodes 
659   j1=aNodes.Lower();
660   j2=aNodes.Upper();
661   for (j=j1; j<=j2; ++j) {
662     if (!aMBN.Contains(j)) {
663       aP=aNodes(j).Transformed(aTrsf);
664       aLP.Append(aP);
665     }
666   }
667   //
668   aNb=aLP.Extent();
669   //
670   if (!aNb && myNbPntsMin) { 
671     // try to fill it yourself
672     Standard_Boolean bIsDone;
673     Standard_Integer aN1, aN2;
674     Handle(Geom_Surface) aS;
675     GeomAdaptor_Surface aGAS;
676     GeomAbs_SurfaceType aType;
677     //
678     aS=BRep_Tool::Surface(aF);
679     aGAS.Load(aS);
680     aType=aGAS.GetType();
681     if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
682       // inner links
683       aNbLinks=aMPKI.Extent();
684       aIt.Initialize(aMPKI);
685       for (; aIt.More(); aIt.Next()) {
686         iCnt=aIt.Value();
687         if (iCnt>1) {
688           // take the first having occured inner link
689           // and discretize it
690           const GEOMAlgo_PassKey& aPK=aIt.Key();
691           //qf
692           /*
693           aNbMax=aPK.NbMax();
694           pIds=(Standard_Integer*)aPK.Key();
695           aN1=*(pIds+aNbMax-1);
696           aN2=*(pIds+aNbMax-2);
697           */
698           //
699           aN1=(Standard_Integer)aPK.Id(1);
700           aN2=(Standard_Integer)aPK.Id(2);
701           //qt
702           aP1=aNodes(aN1).Transformed(aTrsf);
703           aP2=aNodes(aN2).Transformed(aTrsf);
704           //
705           if (aType==GeomAbs_Cylinder) {
706             Standard_Real aTolSM;
707             gp_Cylinder aCyl;
708             //
709             aTolSM=1.523e-6;//~1.-cos(0.1 deg)
710             aCyl=aGAS.Cylinder();
711             if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
712               continue;
713             }
714           }
715           //
716           BRepLib_MakeEdge aBME(aP1, aP2);
717           bIsDone=aBME.IsDone();
718           if (!bIsDone) {
719             myErrorStatus=30; //can not obtain the line fron the link
720             return;
721           }
722           //
723           const TopoDS_Shape& aSx=aBME.Shape();
724           const TopoDS_Edge& aE=TopoDS::Edge(aSx);
725           //
726           InnerPoints(aE, myNbPntsMin, aLP);
727           break;
728         }// if (iCnt>1)
729       }// for (; aIt.More(); aIt.Next())
730     }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) 
731   }// if (!aNb && myNbPntsMin) { 
732 }
733 //=======================================================================
734 //function : InnerPoints
735 //purpose  : 
736 //=======================================================================
737   void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
738                                           GEOMAlgo_ListOfPnt& aLP)
739 {
740   myErrorStatus=0;
741   //
742   Standard_Integer j, aNbNodes, aIndex, aNb;
743   Handle(Poly_PolygonOnTriangulation) aPTE;
744   Handle(Poly_Triangulation) aTRE;
745   TopLoc_Location aLoc;
746   gp_Pnt aP;
747   //
748   aLP.Clear();
749   BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
750   if (aTRE.IsNull() || aPTE.IsNull()) {
751     myErrorStatus=20; // no triangulation found
752     return;  
753   }
754   //
755   const gp_Trsf& aTrsf=aLoc.Transformation();
756   const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
757   //
758   aNbNodes=aPTE->NbNodes();
759   const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
760   for (j=2; j<aNbNodes; ++j) {
761     aIndex=aInds(j);
762     aP=aNodes(aIndex).Transformed(aTrsf);
763     aLP.Append(aP);
764   }
765   //
766   aNb=aLP.Extent();
767   if (!aNb && myNbPntsMin) { 
768     // try to fill it yourself
769     InnerPoints(aE, myNbPntsMin, aLP);
770     aNb=aLP.Extent();
771     
772   }
773 }
774 //=======================================================================
775 //function : InnerPoints
776 //purpose  : 
777 //=======================================================================
778   void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
779                                           const Standard_Integer aNbPntsMin,
780                                           GEOMAlgo_ListOfPnt& aLP)
781 {
782   // try to fill it yourself
783   Standard_Boolean bInf1, bInf2;
784   Standard_Integer j, aNbT;
785   Standard_Real dT, aT, aT1, aT2;
786   gp_Pnt aP;
787   Handle(Geom_Curve) aC3D;
788   //
789   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
790   if (aC3D.IsNull()) {
791     return;
792   }
793   //
794   bInf1=Precision::IsNegativeInfinite(aT1);
795   bInf2=Precision::IsPositiveInfinite(aT2);
796   if (bInf1 || bInf2) {
797     return;
798   }
799   //
800   aNbT=myNbPntsMin+1;
801   dT=(aT2-aT1)/aNbT;
802   for (j=1; j<=aNbPntsMin; ++j) {
803     aT=aT1+j*dT;
804     aC3D->D0(aT, aP);
805     aLP.Append(aP);
806   }
807 }
808
809 //
810 // myErrorStatus :
811 //
812 // 10 -myClsf=NULL
813 // 11 -myShape=NULL
814 // 12 -unallowed type of subshapes 
815 // 13 -unallowed state  
816 // 15 -unallowed surface type
817 // 20- no triangulation found
818 // 30- can not obtain the line from the link
819 // 40- point can not be classified
820 // 41- invalid data for classifier
821