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