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