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