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