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