Salome HOME
[bos #38360] [CEA] improve performances of exportXAO and PublishToStudy
[modules/shaper.git] / src / GeomAPI / GeomAPI_IndexedMapOfShape.cpp
1 // Copyright (C) 2014-2024  CEA, EDF
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 email : webmaster.salome@opencascade.com
18 //
19
20 #include <GeomAPI_IndexedMapOfShape.h>
21
22 #include <gp_Trsf.hxx>
23 #include <TopExp.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <TopLoc_Location.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopTools_IndexedMapOfShape.hxx>
28
29 GeomAPI_IndexedMapOfShape::GeomAPI_IndexedMapOfShape(const std::shared_ptr<GeomAPI_Shape> theMainShape)
30 {
31   MapShapes(theMainShape);
32 }
33
34 void GeomAPI_IndexedMapOfShape::MapShapes(const std::shared_ptr<GeomAPI_Shape> theMainShape)
35 {
36   if (!empty()) {
37     implPtr<TopTools_IndexedMapOfShape>()->Clear();
38   }
39
40   TopoDS_Shape aMainShape = theMainShape->impl<TopoDS_Shape>();
41   if (!aMainShape.IsNull()) {
42     TopTools_IndexedMapOfShape aSubShapesMap;
43     TopExp::MapShapes(aMainShape, aSubShapesMap);
44
45     setImpl(new TopTools_IndexedMapOfShape(aSubShapesMap));
46   }
47 }
48
49 int GeomAPI_IndexedMapOfShape::FindIndex(std::shared_ptr<GeomAPI_Shape> theKey)
50 {
51   return impl<TopTools_IndexedMapOfShape>().FindIndex(theKey->impl<TopoDS_Shape>());
52 }
53
54 // Returns true if transformations are equal with the given precision
55 static bool isEqual(const gp_Trsf& theT1, const gp_Trsf& theT2, const double thePrecision)
56 {
57   for(int aRow = 1; aRow < 4; aRow++) {
58     for(int aCol = 1; aCol < 5; aCol++) {
59       double aDiff = theT1.Value(aRow, aCol) - theT2.Value(aRow, aCol);
60       if (aDiff < 0) aDiff = -aDiff;
61       if (aDiff > thePrecision)
62         return false;
63     }
64   }
65   return true;
66 }
67
68 int GeomAPI_IndexedMapOfShape::FindIndexEqualLocations(std::shared_ptr<GeomAPI_Shape> theKey)
69 {
70   int anID = impl<TopTools_IndexedMapOfShape>().FindIndex(theKey->impl<TopoDS_Shape>());
71   if (anID == 0) {
72     // Try to search shape with the same location if TopLoc_Location is different.
73     // It's a special fix for the problem related to the Placement of parts
74     // feature - it adds additional transformation to all results and groups.
75     const TopoDS_Shape& aMainShape = impl<TopTools_IndexedMapOfShape>().FindKey(1);
76     const TopoDS_Shape& aSubShape = theKey->impl<TopoDS_Shape>();
77     TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
78     for (; anExp.More(); anExp.Next()) {
79       if (anExp.Current().TShape() == aSubShape.TShape()) {
80         const TopLoc_Location aLoc1 = anExp.Current().Location();
81         if (isEqual(aLoc1.Transformation(), aSubShape.Location().Transformation(), 1.e-7)) {
82           anID = impl<TopTools_IndexedMapOfShape>().FindIndex(anExp.Current());
83           break;
84         }
85       }
86     }
87   }
88   return anID;
89 }
90
91 GeomAPI_IndexedMapOfShape::~GeomAPI_IndexedMapOfShape()
92 {
93   if (!empty()) {
94     implPtr<TopTools_IndexedMapOfShape>()->Clear();
95   }
96 }