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