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