Salome HOME
Merge branch 'master' of https://codev-tuleap.cea.fr/plugins/git/salome/shaper
[modules/shaper.git] / src / GeomAPI / GeomAPI_Shape.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "GeomAPI_Shape.h"
22
23 #include <GeomAPI_Vertex.h>
24 #include <GeomAPI_Edge.h>
25 #include <GeomAPI_Wire.h>
26 #include <GeomAPI_Face.h>
27 #include <GeomAPI_Shell.h>
28 #include <GeomAPI_Solid.h>
29
30 #include <BRep_Tool.hxx>
31 #include <BRepAlgoAPI_Section.hxx>
32 #include <BRepBndLib.hxx>
33 #include <BRepBuilderAPI_FindPlane.hxx>
34 #include <BRepExtrema_DistShapeShape.hxx>
35 #include <BRepTools.hxx>
36 #include <Bnd_Box.hxx>
37 #include <Geom_Circle.hxx>
38 #include <Geom_Conic.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Ellipse.hxx>
41 #include <Geom_Hyperbola.hxx>
42 #include <Geom_Line.hxx>
43 #include <Geom_Parabola.hxx>
44 #include <Geom_Plane.hxx>
45 #include <Geom_RectangularTrimmedSurface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopoDS.hxx>
49 #include <TopoDS_Iterator.hxx>
50 #include <TopoDS_Shape.hxx>
51 #include <NCollection_List.hxx>
52
53 #include <BOPAlgo_CheckerSI.hxx>
54 #include <BOPDS_DS.hxx>
55
56 #include <sstream>
57 #include <algorithm> // for std::transform
58
59 #include <BRepTools.hxx>
60
61 #define MY_SHAPE implPtr<TopoDS_Shape>()
62
63 GeomAPI_Shape::GeomAPI_Shape()
64     : GeomAPI_Interface(new TopoDS_Shape())
65 {
66 }
67
68 std::shared_ptr<GeomAPI_Shape> GeomAPI_Shape::emptyCopied() const
69 {
70   GeomShapePtr aShape(new GeomAPI_Shape());
71   aShape->setImpl(new TopoDS_Shape(MY_SHAPE->EmptyCopied()));
72   return aShape;
73 }
74
75 bool GeomAPI_Shape::isNull() const
76 {
77   return MY_SHAPE->IsNull() == Standard_True;
78 }
79
80 bool GeomAPI_Shape::isEqual(const std::shared_ptr<GeomAPI_Shape> theShape) const
81 {
82   if (!theShape.get())
83     return false;
84   if (isNull())
85     return theShape->isNull();
86   if (theShape->isNull())
87     return false;
88
89   return MY_SHAPE->IsEqual(theShape->impl<TopoDS_Shape>()) == Standard_True;
90 }
91
92 bool GeomAPI_Shape::isSame(const std::shared_ptr<GeomAPI_Shape> theShape) const
93 {
94   if (!theShape.get())
95     return false;
96   if (isNull())
97     return theShape->isNull();
98   if (theShape->isNull())
99     return false;
100
101   return MY_SHAPE->IsSame(theShape->impl<TopoDS_Shape>()) == Standard_True;
102 }
103
104 bool GeomAPI_Shape::isVertex() const
105 {
106   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
107   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX;
108 }
109
110 bool GeomAPI_Shape::isEdge() const
111 {
112   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
113   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_EDGE;
114 }
115
116 bool GeomAPI_Shape::isWire() const
117 {
118   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
119   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_WIRE;
120 }
121
122 bool GeomAPI_Shape::isFace() const
123 {
124   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
125   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_FACE;
126 }
127
128 bool GeomAPI_Shape::isShell() const
129 {
130   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
131   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_SHELL;
132 }
133
134 bool GeomAPI_Shape::isCompound() const
135 {
136   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
137   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND;
138 }
139
140 bool GeomAPI_Shape::isCompoundOfSolids() const
141 {
142   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
143   if (aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND)
144     return false;
145   bool isAtLeastOne = false;
146   for(TopoDS_Iterator aSubs(aShape); aSubs.More(); aSubs.Next()) {
147     if (aSubs.Value().IsNull() || aSubs.Value().ShapeType() != TopAbs_SOLID)
148       return false;
149     isAtLeastOne = true;
150   }
151   return isAtLeastOne;
152 }
153
154 GeomAPI_Shape::ShapeType GeomAPI_Shape::typeOfCompoundShapes() const
155 {
156   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
157   if (aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND)
158     return SHAPE;
159   int aType = -1;
160   for(TopoDS_Iterator aSubs(aShape); aSubs.More(); aSubs.Next()) {
161     if (!aSubs.Value().IsNull()) {
162       if (aType == -1)
163         aType = aSubs.Value().ShapeType();
164       else if (aSubs.Value().ShapeType() != aType)
165         return SHAPE;
166     }
167   }
168   return (GeomAPI_Shape::ShapeType) aType;
169 }
170
171 // adds the nopt-compound elements recursively to the list
172 static void addSimpleToList(const TopoDS_Shape& theShape, NCollection_List<TopoDS_Shape>& theList)
173 {
174   if (!theShape.IsNull()) {
175     if (theShape.ShapeType() == TopAbs_COMPOUND) {
176       for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
177         addSimpleToList(aSubs.Value(), theList);
178       }
179     } else {
180       theList.Append(theShape);
181     }
182   }
183 }
184
185 bool GeomAPI_Shape::isConnectedTopology() const
186 {
187   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
188   if (aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND)
189     return false;
190   // list of simple elements that are not detected in connection to others
191   NCollection_List<TopoDS_Shape> aNotConnected;
192   addSimpleToList(aShape, aNotConnected);
193   if (aNotConnected.IsEmpty()) // an empty compound
194     return false;
195
196   // collect here the group of connected subs, starting with one first element
197   NCollection_List<TopoDS_Shape> aNewConnected;
198   aNewConnected.Append(aNotConnected.First());
199   aNotConnected.RemoveFirst();
200   // iterate until some new element become connected
201   while(!aNewConnected.IsEmpty() && !aNotConnected.IsEmpty()) {
202     NCollection_List<TopoDS_Shape> aNew; // very new connected to new connected
203     NCollection_List<TopoDS_Shape>::Iterator aNotIter(aNotConnected);
204     while(aNotIter.More()) {
205       // optimization to avoid TopExp_Explorer double-cycle, collect all vertices in the list first
206       NCollection_List<TopoDS_Shape> aNotVertices;
207       for(TopExp_Explorer anExp1(aNotIter.Value(), TopAbs_VERTEX); anExp1.More(); anExp1.Next()) {
208         aNotVertices.Append(anExp1.Current());
209       }
210
211       bool aConnected =  false;
212       NCollection_List<TopoDS_Shape>::Iterator aNewIter(aNewConnected);
213       for(; !aConnected && aNewIter.More(); aNewIter.Next()) {
214         // checking topological connecion of aNotIter and aNewIter
215         // (if shapes are connected, vertices are connected for sure)
216         TopExp_Explorer anExp2(aNewIter.Value(), TopAbs_VERTEX);
217         for(; !aConnected && anExp2.More(); anExp2.Next()) {
218           NCollection_List<TopoDS_Shape>::Iterator aNotIter(aNotVertices);
219           for(; aNotIter.More(); aNotIter.Next()) {
220             if (aNotIter.Value().IsSame(anExp2.Current())) {
221               aConnected = true;
222               break;
223             }
224           }
225         }
226       }
227       if (aConnected) {
228         aNew.Append(aNotIter.Value());
229         aNotConnected.Remove(aNotIter);
230       } else {
231         aNotIter.Next();
232       }
233     }
234     // remove all new connected and put to this list very new connected
235     aNewConnected.Clear();
236     aNewConnected.Append(aNew);
237   }
238   return aNotConnected.IsEmpty() == Standard_True;
239 }
240
241 bool GeomAPI_Shape::isSolid() const
242 {
243   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
244   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_SOLID;
245 }
246
247 bool GeomAPI_Shape::isCompSolid() const
248 {
249   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
250   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPSOLID;
251 }
252
253 bool GeomAPI_Shape::isPlanar() const
254 {
255   TopoDS_Shape aShape = impl<TopoDS_Shape>();
256
257   if(aShape.IsNull()) {
258     return false;
259   }
260
261   TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
262   if(aShapeType == TopAbs_COMPOUND) {
263     TopoDS_Iterator anIt(aShape);
264     int aShNum = 0;
265     for(; anIt.More(); anIt.Next()) {
266       ++aShNum;
267     }
268     if(aShNum == 1) {
269       anIt.Initialize(aShape);
270       aShape = anIt.Value();
271     }
272   }
273
274   aShapeType = aShape.ShapeType();
275   if(aShapeType == TopAbs_VERTEX) {
276     return true;
277   } else if(aShapeType == TopAbs_FACE) {
278     const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
279     Handle(Standard_Type) aType = aSurface->DynamicType();
280
281     if(aType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
282       Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
283         Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
284       aType = aTrimSurface->BasisSurface()->DynamicType();
285     }
286     return (aType == STANDARD_TYPE(Geom_Plane)) == Standard_True;
287   } else {
288     BRepBuilderAPI_FindPlane aFindPlane(aShape);
289     bool isFound = aFindPlane.Found() == Standard_True;
290
291     if(!isFound && aShapeType == TopAbs_EDGE) {
292       Standard_Real aFirst, aLast;
293       Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFirst, aLast);
294       Handle(Standard_Type) aType = aCurve->DynamicType();
295
296       if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
297         Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
298         aType = aTrimCurve->BasisCurve()->DynamicType();
299       }
300
301       if(aType == STANDARD_TYPE(Geom_Line)
302           || aType == STANDARD_TYPE(Geom_Conic)
303           || aType == STANDARD_TYPE(Geom_Circle)
304           || aType == STANDARD_TYPE(Geom_Ellipse)
305           || aType == STANDARD_TYPE(Geom_Hyperbola)
306           || aType == STANDARD_TYPE(Geom_Parabola)) {
307         isFound = true;
308       }
309     }
310
311     return isFound;
312   }
313
314   return false;
315 }
316
317 std::shared_ptr<GeomAPI_Vertex> GeomAPI_Shape::vertex() const
318 {
319   GeomVertexPtr aVertex;
320   if (isVertex()) {
321     const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
322     aVertex = GeomVertexPtr(new GeomAPI_Vertex);
323     aVertex->setImpl(new TopoDS_Shape(aShape));
324   }
325   return aVertex;
326 }
327
328 std::shared_ptr<GeomAPI_Edge> GeomAPI_Shape::edge() const
329 {
330   GeomEdgePtr anEdge;
331   if (isEdge()) {
332     const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
333     anEdge = GeomEdgePtr(new GeomAPI_Edge);
334     anEdge->setImpl(new TopoDS_Shape(aShape));
335   }
336   return anEdge;
337 }
338
339 std::shared_ptr<GeomAPI_Wire> GeomAPI_Shape::wire() const
340 {
341   GeomWirePtr aWire;
342   if (isWire()) {
343     const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
344     aWire = GeomWirePtr(new GeomAPI_Wire);
345     aWire->setImpl(new TopoDS_Shape(aShape));
346   }
347   return aWire;
348 }
349
350 std::shared_ptr<GeomAPI_Face> GeomAPI_Shape::face() const
351 {
352   GeomFacePtr aFace;
353   if (isFace()) {
354     const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
355     aFace = GeomFacePtr(new GeomAPI_Face);
356     aFace->setImpl(new TopoDS_Shape(aShape));
357   }
358   return aFace;
359 }
360
361 std::shared_ptr<GeomAPI_Shell> GeomAPI_Shape::shell() const
362 {
363   GeomShellPtr aShell;
364   if (isShell()) {
365     const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
366     aShell = GeomShellPtr(new GeomAPI_Shell);
367     aShell->setImpl(new TopoDS_Shape(aShape));
368   }
369   return aShell;
370 }
371
372 std::shared_ptr<GeomAPI_Solid> GeomAPI_Shape::solid() const
373 {
374   GeomSolidPtr aSolid;
375   if (isSolid()) {
376     const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
377     aSolid = GeomSolidPtr(new GeomAPI_Solid);
378     aSolid->setImpl(new TopoDS_Shape(aShape));
379   }
380   return aSolid;
381 }
382
383 std::list<std::shared_ptr<GeomAPI_Shape> >
384 GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const
385 {
386   ListOfShape aSubs;
387   const TopoDS_Shape& aShape = impl<TopoDS_Shape>();
388   if (aShape.IsNull())
389     return aSubs;
390
391   for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType);
392        anExp.More(); anExp.Next()) {
393     GeomShapePtr aSub(new GeomAPI_Shape);
394     aSub->setImpl(new TopoDS_Shape(anExp.Current()));
395     aSubs.push_back(aSub);
396   }
397   return aSubs;
398 }
399
400 GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeType() const
401 {
402   const TopoDS_Shape& aShape = impl<TopoDS_Shape>();
403   if (aShape.IsNull())
404     return GeomAPI_Shape::SHAPE;
405
406   ShapeType aST = GeomAPI_Shape::SHAPE;
407
408   switch(aShape.ShapeType()) {
409   case TopAbs_COMPOUND:
410     aST = GeomAPI_Shape::COMPOUND;
411     break;
412   case TopAbs_COMPSOLID:
413     aST = GeomAPI_Shape::COMPSOLID;
414     break;
415   case TopAbs_SOLID:
416     aST = GeomAPI_Shape::SOLID;
417     break;
418   case TopAbs_SHELL:
419     aST = GeomAPI_Shape::SHELL;
420     break;
421   case TopAbs_FACE:
422     aST = GeomAPI_Shape::FACE;
423     break;
424   case TopAbs_WIRE:
425     aST = GeomAPI_Shape::WIRE;
426     break;
427   case TopAbs_EDGE:
428     aST = GeomAPI_Shape::EDGE;
429     break;
430   case TopAbs_VERTEX:
431     aST = GeomAPI_Shape::VERTEX;
432     break;
433   case TopAbs_SHAPE:
434     aST = GeomAPI_Shape::SHAPE;
435     break;
436   }
437
438   return aST;
439 }
440
441 GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeTypeByStr(std::string theType)
442 {
443   std::transform(theType.begin(), theType.end(), theType.begin(), ::toupper);
444   if (theType == "COMPOUND")
445     return COMPOUND;
446   if (theType == "COMPSOLID")
447     return COMPSOLID;
448   if (theType == "SOLID")
449     return SOLID;
450   if (theType == "SHELL")
451     return SHELL;
452   if (theType == "FACE")
453     return FACE;
454   if (theType == "WIRE")
455     return WIRE;
456   if (theType == "EDGE")
457     return EDGE;
458   if (theType == "VERTEX")
459     return VERTEX;
460   return SHAPE; // default
461 }
462
463 std::string GeomAPI_Shape::shapeTypeStr() const
464 {
465   ShapeType aShapeType = shapeType();
466   std::string aShapeTypeStr;
467
468   switch(aShapeType) {
469     case COMPOUND: {
470       aShapeTypeStr = "COMPOUND";
471       break;
472     }
473     case COMPSOLID: {
474       aShapeTypeStr = "COMPSOLID";
475       break;
476     }
477     case SOLID: {
478       aShapeTypeStr = "SOLID";
479       break;
480     }
481     case SHELL: {
482       aShapeTypeStr = "SHELL";
483       break;
484     }
485     case FACE: {
486       aShapeTypeStr = "FACE";
487       break;
488     }
489     case WIRE: {
490       aShapeTypeStr = "WIRE";
491       break;
492     }
493     case EDGE: {
494       aShapeTypeStr = "EDGE";
495       break;
496     }
497     case VERTEX: {
498       aShapeTypeStr = "VERTEX";
499       break;
500     }
501     case SHAPE: {
502       aShapeTypeStr = "SHAPE";
503       break;
504     }
505   }
506
507   return aShapeTypeStr;
508 }
509
510 GeomAPI_Shape::Orientation GeomAPI_Shape::orientation() const
511 {
512   TopAbs_Orientation anOrientation = MY_SHAPE->Orientation();
513
514   switch(anOrientation) {
515     case TopAbs_FORWARD:  return FORWARD;
516     case TopAbs_REVERSED: return REVERSED;
517     case TopAbs_INTERNAL: return INTERNAL;
518     case TopAbs_EXTERNAL: return EXTERNAL;
519     default:              return FORWARD;
520   }
521 }
522
523 void GeomAPI_Shape::setOrientation(const GeomAPI_Shape::Orientation theOrientation)
524 {
525   TopAbs_Orientation anOrientation = MY_SHAPE->Orientation();
526
527   switch(theOrientation) {
528     case FORWARD:  MY_SHAPE->Orientation(TopAbs_FORWARD);  break;
529     case REVERSED: MY_SHAPE->Orientation(TopAbs_REVERSED); break;
530     case INTERNAL: MY_SHAPE->Orientation(TopAbs_INTERNAL); break;
531     case EXTERNAL: MY_SHAPE->Orientation(TopAbs_EXTERNAL); break;
532   }
533 }
534
535 void GeomAPI_Shape::reverse()
536 {
537   MY_SHAPE->Reverse();
538 }
539
540 bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape,
541                                const bool theCheckOrientation) const
542 {
543   if(!theShape.get()) {
544     return false;
545   }
546
547   const TopoDS_Shape& aShapeToSearch = theShape->impl<TopoDS_Shape>();
548   if(aShapeToSearch.IsNull()) {
549     return false;
550   }
551
552   for(TopExp_Explorer anExp(*MY_SHAPE, aShapeToSearch.ShapeType()); anExp.More(); anExp.Next()) {
553     if(theCheckOrientation ?
554        aShapeToSearch.IsEqual(anExp.Current()) : aShapeToSearch.IsSame(anExp.Current())) {
555       return true;
556     }
557   }
558
559   return false;
560 }
561
562 bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmin,
563                                 double& theXmax, double& theYmax, double& theZmax) const
564 {
565   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
566   if (aShape.IsNull())
567     return false;
568   Bnd_Box aBndBox;
569   BRepBndLib::Add(aShape, aBndBox);
570   aBndBox.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax);
571   return true;
572 }
573
574 std::string GeomAPI_Shape::getShapeStream() const
575 {
576   std::ostringstream aStream;
577   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
578   BRepTools::Write(aShape, aStream);
579   return aStream.str();
580 }
581
582 GeomShapePtr GeomAPI_Shape::intersect(const GeomShapePtr theShape) const
583 {
584   const TopoDS_Shape& aShape1 = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
585   const TopoDS_Shape& aShape2 = theShape->impl<TopoDS_Shape>();
586
587   BRepAlgoAPI_Section aCommon(aShape1, aShape2);
588   if (!aCommon.IsDone())
589     return GeomShapePtr();
590
591   TopoDS_Shape aResult = aCommon.Shape();
592   if (aResult.ShapeType() == TopAbs_COMPOUND) {
593     NCollection_List<TopoDS_Shape> aSubs;
594     addSimpleToList(aResult, aSubs);
595     if(aSubs.Size() == 1) {
596       aResult = aSubs.First();
597     } else if(aSubs.Size() == 0) {
598       return GeomShapePtr();
599     }
600   }
601
602   GeomShapePtr aResShape(new GeomAPI_Shape);
603   aResShape->setImpl(new TopoDS_Shape(aResult));
604   return aResShape;
605 }
606
607 bool GeomAPI_Shape::isIntersect(const GeomShapePtr theShape) const
608 {
609   if(!theShape.get()) {
610     return false;
611   }
612
613   const TopoDS_Shape& aShape1 = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
614   const TopoDS_Shape& aShape2 = theShape->impl<TopoDS_Shape>();
615
616   BRepExtrema_DistShapeShape aDist(aShape1, aShape2);
617   aDist.Perform();
618   if(aDist.IsDone() && aDist.Value() < Precision::Confusion()) {
619     return true;
620   }
621
622   return false;
623 }
624
625 void GeomAPI_Shape::translate(const std::shared_ptr<GeomAPI_Dir> theDir, const double theOffset)
626 {
627   gp_Dir aDir = theDir->impl<gp_Dir>();
628   gp_Vec aTrsfVec(aDir.XYZ() * theOffset);
629   gp_Trsf aTranslation;
630   aTranslation.SetTranslation(aTrsfVec);
631   TopoDS_Shape aResult = MY_SHAPE->Moved(aTranslation);
632   setImpl(new TopoDS_Shape(aResult));
633 }
634
635 bool GeomAPI_Shape::isSelfIntersected(const int theLevelOfCheck) const
636 {
637   BOPAlgo_CheckerSI aCSI;  // checker of self-interferences
638   aCSI.SetLevelOfCheck(theLevelOfCheck);
639   TopTools_ListOfShape aList;
640   const TopoDS_Shape& aThisShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
641   aList.Append(aThisShape);
642   aCSI.SetArguments(aList);
643   aCSI.Perform();
644   if (aCSI.HasErrors() || aCSI.DS().Interferences().Extent() > 0) {
645     return true;
646   }
647
648   return false;
649 }