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