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