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