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