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