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