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