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