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