Salome HOME
SMH: Add forgotten files
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_FinderShapeOn.cxx
1 // File:        GEOMAlgo_FinderShapeOn.cxx
2 // Created:     Tue Jan 11 14:44:31 2005
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <GEOMAlgo_FinderShapeOn.ixx>
8
9 #include <gp_Pnt.hxx>
10
11 #include <TopAbs_ShapeEnum.hxx>
12 #include <TopAbs_Orientation.hxx>
13
14 #include <TopoDS.hxx>
15 #include <TopoDS_Face.hxx>
16 #include <TopoDS_Shape.hxx>
17 #include <TopoDS_Compound.hxx>
18 #include <TopoDS_Shell.hxx>
19 #include <TopoDS_Solid.hxx>
20 #include <TopoDS_Vertex.hxx>
21 #include <TopoDS_Edge.hxx>
22 #include <TopoDS_Iterator.hxx>
23
24 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 #include <TopTools_IndexedMapOfShape.hxx>
26 #include <TopTools_DataMapOfShapeShape.hxx>
27
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30
31 #include <TopExp.hxx>
32 #include <TopExp_Explorer.hxx>
33
34 #include <BRepLib_MakeFace.hxx>
35 #include <BRepLib_FaceError.hxx>
36
37 #include <BOPTools_DSFiller.hxx>
38
39 #include <GEOMAlgo_WireSolid.hxx>
40 #include <GEOMAlgo_ShellSolid.hxx>
41 #include <GEOMAlgo_VertexSolid.hxx>
42 #include <GEOMAlgo_ShapeSolid.hxx>
43 #include <GEOMAlgo_SolidSolid.hxx>
44 #include <GEOMAlgo_SurfaceTools.hxx>
45 #include <GEOMAlgo_Tools.hxx>
46
47 //=======================================================================
48 //function : GEOMAlgo_FinderShapeOn
49 //purpose  : 
50 //=======================================================================
51 GEOMAlgo_FinderShapeOn::GEOMAlgo_FinderShapeOn()
52 :
53   GEOMAlgo_ShapeAlgo()
54 {
55   myTolerance=0.0001;
56   myShapeType=TopAbs_VERTEX;
57   myState=GEOMAlgo_ST_UNKNOWN;
58   myIsAnalytic=Standard_True;
59 }
60 //=======================================================================
61 //function : ~
62 //purpose  : 
63 //=======================================================================
64 GEOMAlgo_FinderShapeOn::~GEOMAlgo_FinderShapeOn()
65 {
66 }
67 //=======================================================================
68 //function : SetSurface
69 //purpose  : 
70 //=======================================================================
71 void GEOMAlgo_FinderShapeOn::SetSurface(const Handle(Geom_Surface)& aS)
72 {
73   mySurface=aS;
74 }
75 //=======================================================================
76 //function : Surface
77 //purpose  : 
78 //=======================================================================
79 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn::Surface() const
80 {
81   return mySurface;
82 }
83 //=======================================================================
84 //function : SetShapeType
85 //purpose  : 
86 //=======================================================================
87 void GEOMAlgo_FinderShapeOn::SetShapeType(const TopAbs_ShapeEnum aType)
88 {
89   myShapeType=aType;
90 }
91 //=======================================================================
92 //function : ShapeType
93 //purpose  : 
94 //=======================================================================
95 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn::ShapeType()const
96 {
97   return myShapeType;
98 }
99 //=======================================================================
100 //function : SetState
101 //purpose  : 
102 //=======================================================================
103 void GEOMAlgo_FinderShapeOn::SetState(const GEOMAlgo_State aState)
104 {
105   myState=aState;
106 }
107 //=======================================================================
108 //function : State
109 //purpose  : 
110 //=======================================================================
111 GEOMAlgo_State GEOMAlgo_FinderShapeOn::State() const
112 {
113   return myState;
114 }
115 //=======================================================================
116 // function: Shapes
117 // purpose: 
118 //=======================================================================
119 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn::Shapes() const
120 {
121   Standard_Boolean bIsConformState;
122   Standard_Integer i, aNb;
123   TopAbs_State aSt;
124   TopTools_ListOfShape* pL;
125   //
126   pL=(TopTools_ListOfShape*) &myLS;
127   pL->Clear();
128   //
129   aNb=myMSS.Extent();
130   for (i=1; i<=aNb; ++i) {
131     const TopoDS_Shape& aS=myMSS.FindKey(i);
132     aSt=myMSS.FindFromIndex(i);
133     //
134     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
135     if (bIsConformState) {
136       pL->Append(aS);
137     }
138   }
139   return myLS;
140 }
141 //=======================================================================
142 //function : Perform
143 //purpose  : 
144 //=======================================================================
145 void GEOMAlgo_FinderShapeOn::Perform()
146 {
147   myErrorStatus=0;
148   myWarningStatus=0;
149   myLS.Clear();
150   myMSS.Clear();
151   //
152   if (!myResult.IsNull()){
153     myResult.Nullify();
154   }
155   //
156   CheckData();
157   if(myErrorStatus) {
158     return;
159   }
160   //
161   myIsAnalytic=GEOMAlgo_SurfaceTools::IsAnalytic(mySurface);
162   //
163   MakeArgument1();
164   if(myErrorStatus) {
165     return;
166   }
167   //
168   if (myIsAnalytic && myShapeType==TopAbs_VERTEX) {
169     FindVertices();
170     return;
171   }
172   //
173   MakeArgument2();
174   if(myErrorStatus) {
175     return;
176   }
177   //
178   Find();
179   if(myErrorStatus || myWarningStatus) {
180     return;
181   }
182   //
183 }
184 //=======================================================================
185 //function : FindVertices
186 //purpose  : 
187 //=======================================================================
188 void GEOMAlgo_FinderShapeOn::FindVertices()
189
190   Standard_Integer i, aNb, iErr;
191   TopAbs_State aSt;
192   TopAbs_Orientation aOr;
193   gp_Pnt aP;
194   TopTools_IndexedMapOfShape aM;
195   //
196   TopExp::MapShapes(myArg1, TopAbs_FACE, aM);
197   const TopoDS_Face& aF=TopoDS::Face(aM(1));
198   aOr=aF.Orientation();
199   //
200   aM.Clear();
201   TopExp::MapShapes(myShape, myShapeType, aM);
202   aNb=aM.Extent();
203   if (!aNb) {
204     myWarningStatus=10; // No found subshapes of type myShapeType
205     return;
206   }
207   //
208   for (i=1; i<=aNb; ++i) {
209     const TopoDS_Shape& aS=aM(i);
210     const TopoDS_Vertex& aV=TopoDS::Vertex(aS);
211     aP=BRep_Tool::Pnt(aV);
212     iErr=GEOMAlgo_SurfaceTools::GetState(aP, mySurface, myTolerance, aSt);
213     if (aOr==TopAbs_REVERSED) {
214       aSt=GEOMAlgo_SurfaceTools::ReverseState(aSt);
215     }
216     myMSS.Add(aS, aSt);
217   }
218 }
219 //=======================================================================
220 //function : Find
221 //purpose  : 
222 //=======================================================================
223 void GEOMAlgo_FinderShapeOn::Find()
224 {
225   Standard_Integer i, aNb;
226   Standard_Boolean bICS;
227   TopTools_IndexedMapOfShape aM;
228   //
229   TopExp::MapShapes(myArg2, myShapeType, aM);
230   //
231   aNb=aM.Extent();
232   if (!aNb) {
233     myWarningStatus=10; // No found subshapes of type myShapeType
234     return;
235   }
236   //
237   bICS=GEOMAlgo_Tools::IsCompositeShape(myArg2);
238   if (!bICS || myIsAnalytic) {
239     TopoDS_Compound aCmp;
240     BRep_Builder aBB;
241     //
242     aBB.MakeCompound(aCmp);
243     for (i=1; i<=aNb; ++i) {
244       const TopoDS_Shape& aSi=aM(i);
245       aBB.Add(aCmp, aSi);
246     }
247     //
248     aM.Clear();
249     aM.Add(aCmp);
250     aNb=1;
251   }
252   //
253   for (i=1; i<=aNb; ++i) {
254     const TopoDS_Shape& aS=aM(i);
255     Find(aS);
256     if (myErrorStatus) {
257       return;
258     }
259   }
260 }
261 //=======================================================================
262 //function : Find
263 //purpose  : 
264 //=======================================================================
265 void GEOMAlgo_FinderShapeOn::Find(const TopoDS_Shape& aS)
266 {
267   myErrorStatus=0;
268   //
269   Standard_Boolean bIsDone;
270   Standard_Integer i, iErr;
271   TopAbs_State aSts[]={TopAbs_IN, TopAbs_OUT, TopAbs_ON};
272   TopTools_ListIteratorOfListOfShape aIt;
273   BOPTools_DSFiller aDF;
274   //
275   // 1. Prepare DSFiller
276   aDF.SetShapes (myArg1, aS);
277   bIsDone=aDF.IsDone();
278   if (!bIsDone) {
279     myErrorStatus=30; // wrong args are used for DSFiller
280     return;
281   }
282   aDF.Perform();
283   bIsDone=aDF.IsDone();
284   if (!bIsDone) {
285     myErrorStatus=31; // DSFiller failed
286     return;
287   }
288   // 
289   // 2. Find shapes
290   GEOMAlgo_ShapeSolid* pSS;
291   GEOMAlgo_VertexSolid aVXS;
292   GEOMAlgo_WireSolid aWRS;
293   GEOMAlgo_ShellSolid aSHS;
294   GEOMAlgo_SolidSolid aSLS;
295   //
296   pSS=NULL;
297   //
298   switch (myShapeType) {
299     case TopAbs_VERTEX:
300       pSS=&aVXS;
301       break;
302     case TopAbs_EDGE:
303       pSS=&aWRS;
304       break;
305     case TopAbs_FACE:
306       pSS=&aSHS;
307       break;
308     case TopAbs_SOLID:
309       aSLS.SetShape2(myArg2);
310       pSS=&aSLS;
311       break;
312     default:
313       myErrorStatus=12; // unallowed subshape type
314       return;
315   }
316   //
317   pSS->SetFiller(aDF);
318   pSS->Perform();
319   iErr=pSS->ErrorStatus();
320   if (iErr) {
321     myErrorStatus=32; // builder ShapeSolid failed
322     return;
323   }
324   //
325   for (i=0; i<3; ++i) {
326     const TopTools_ListOfShape& aLS=pSS->Shapes(aSts[i]);
327     aIt.Initialize(aLS);
328     for (; aIt.More(); aIt.Next()) {
329       const TopoDS_Shape& aSImage=aIt.Value(); 
330       if (myImages.IsBound(aSImage)) { 
331         const TopoDS_Shape& aSx=myImages.Find(aSImage); 
332         myMSS.Add(aSx, aSts[i]);
333       }
334       else {
335         myErrorStatus=33;// can not find original shape
336         return; 
337       }
338     }
339   }
340 }
341 //=======================================================================
342 //function : MakeArgument1
343 //purpose  : 
344 //=======================================================================
345 void GEOMAlgo_FinderShapeOn::MakeArgument1()
346 {
347   myErrorStatus=0;
348   //
349   Standard_Integer i, aNb;
350   TopAbs_ShapeEnum aType;
351   BRepLib_FaceError aFErr;
352   BRepLib_MakeFace aMF;
353   TopTools_IndexedMapOfShape aM;
354   BRep_Builder aBB;
355   TopoDS_Face aFace;
356   TopoDS_Shell aSh;
357   TopoDS_Solid aSd;
358   //
359   // Argument 1
360   if (!myIsAnalytic) {
361     aMF.Init(mySurface, Standard_True);
362     aFErr=aMF.Error();
363     if (aFErr!=BRepLib_FaceDone) {
364       myErrorStatus=20; // can not build the face
365       return;
366     }
367     //
368     const TopoDS_Shape& aF=aMF.Shape();
369     aFace=TopoDS::Face(aF);
370     //
371     // update tolerances
372     aM.Add(aF);
373     TopExp::MapShapes(aF, TopAbs_VERTEX, aM);
374     TopExp::MapShapes(aF, TopAbs_EDGE, aM);
375     aNb=aM.Extent();
376     for (i=1; i<=aNb; ++i) {
377       const TopoDS_Shape& aS=aM(i);
378       aType=aS.ShapeType();
379       switch (aType) {
380       case TopAbs_VERTEX: {
381         const TopoDS_Vertex& aVx=TopoDS::Vertex(aS);
382         aBB.UpdateVertex(aVx, myTolerance);
383       }
384         break;
385       case TopAbs_EDGE: {
386         const TopoDS_Edge& aEx=TopoDS::Edge(aS);
387         aBB.UpdateEdge(aEx, myTolerance);
388       }
389         break;
390       case TopAbs_FACE: {
391         const TopoDS_Face& aFx=TopoDS::Face(aS);
392         aBB.UpdateFace(aFx, myTolerance);
393       }
394         break;
395       default:
396         break;
397       }
398     }
399   } //  
400   else {
401     aBB.MakeFace(aFace, mySurface, myTolerance);
402   }
403   //
404   // make solid
405   aBB.MakeShell(aSh);
406   aBB.Add(aSh, aFace);
407   aBB.MakeSolid(aSd);
408   aBB.Add(aSd, aSh);
409   myArg1=aSd;
410 }
411 //=======================================================================
412 //function : MakeArgument2
413 //purpose  : 
414 //=======================================================================
415 void GEOMAlgo_FinderShapeOn::MakeArgument2()
416 {
417   myErrorStatus=0;
418   //
419   TopoDS_Shape aSC;
420   TopTools_DataMapOfShapeShape aOriginals;
421   //
422   myImages.Clear();
423   //
424   GEOMAlgo_FinderShapeOn::CopySource(myShape, myImages, aOriginals, aSC);
425   //
426   myArg2=aSC;
427 }
428 //=======================================================================
429 //function : CheckData
430 //purpose  : 
431 //=======================================================================
432 void GEOMAlgo_FinderShapeOn::CheckData()
433 {
434   myErrorStatus=0;
435   //
436   if(mySurface.IsNull()) {
437     myErrorStatus=10; // mySurface=NULL
438     return;
439   }
440   //
441   if (myShape.IsNull()) {
442     myErrorStatus=11; // myShape=NULL
443     return;
444   }
445   //
446   if (!(myShapeType==TopAbs_VERTEX ||
447         myShapeType==TopAbs_EDGE ||
448         myShapeType==TopAbs_FACE ||
449         myShapeType==TopAbs_SOLID)) {
450     myErrorStatus=12; // unallowed subshape type
451     return;
452   }
453   //
454   if (myState==GEOMAlgo_ST_UNKNOWN || 
455       myState==GEOMAlgo_ST_INOUT) {
456     myErrorStatus=13; // unallowed state type
457     return;
458   }
459 }
460 //
461 //=======================================================================
462 //function : CopySource
463 //purpose  : 
464 //=======================================================================
465 void GEOMAlgo_FinderShapeOn::CopySource(const TopoDS_Shape& aE,
466                                         TopTools_DataMapOfShapeShape& aImages,
467                                         TopTools_DataMapOfShapeShape& aOriginals,
468                                         TopoDS_Shape& aEx)
469 {
470   Standard_Boolean bFree;
471   TopAbs_ShapeEnum aType;
472   Standard_Integer aR;
473   BRep_Builder BB;
474   TopoDS_Iterator aIt;
475   //
476   aType=aE.ShapeType();
477   //
478   if (aOriginals.IsBound(aE)) {
479     aEx=aOriginals.ChangeFind(aE);
480     return;
481   }
482   else {
483     aEx=aE.EmptyCopied();
484     aOriginals.Bind(aE, aEx);
485     aImages.Bind(aEx, aE);
486   }
487   //
488   aR=(Standard_Integer)aType+1;
489   if (aR>TopAbs_VERTEX) {
490     return;
491   }
492   //
493   bFree=aEx.Free();
494   aEx.Free(Standard_True);
495   //
496   aType=(TopAbs_ShapeEnum) aR;
497   //
498   aIt.Initialize(aE);//, Standard_False);
499   for (; aIt.More();  aIt.Next()) {
500     const TopoDS_Shape& aV=aIt.Value();
501     TopoDS_Shape aVx;
502     //
503     CopySource (aV, aImages, aOriginals, aVx);  
504     //
505     aVx.Orientation(aV.Orientation());
506     BB.Add(aEx, aVx);
507   }
508   //
509   aEx.Free(bFree);
510 }
511
512 //
513 // myErrorStatus :
514 //
515 // 10 -mySurface=NULL
516 // 11 -myShape=NULL
517 // 12 -unallowed type of subshapes 
518 // 13 -unallowed state  
519 // 20 -can not build the face
520 // 30 -wrong args are used for DSFiller
521 // 31 -DSFiller failed
522 // 32 -builder ShapeSolid failed
523 // 33 -can not find original shape
524 //
525 // myWarningStatus
526 //
527 // 10 -subshapes of type myShapeType can not be fond in myShape
528