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