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