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