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