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