Salome HOME
f4faf30f40e32b5c5c2f11ea8664be52c8b8583d
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_GetInPlace_2.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 // File:        GEOMAlgo_GetInPlace_2.cxx
23 // Created:
24 // Author:      Peter KURNEV
25
26 #include <GEOMAlgo_GetInPlace.hxx>
27
28 #include <TopAbs_ShapeEnum.hxx>
29
30 #include <gp_Pnt.hxx>
31
32 #include <TopoDS_Iterator.hxx>
33 #include <TopoDS_Compound.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Vertex.hxx>
36
37 #include <BRep_Tool.hxx>
38 #include <BRep_Builder.hxx>
39
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TopTools_MapIteratorOfMapOfShape.hxx>
42 #include <TopTools_ListOfShape.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44
45 #include <TopExp.hxx>
46
47 #include <GProp_GProps.hxx>
48 #include <BRepGProp.hxx>
49
50
51 static
52   Standard_Integer Dimension(const TopAbs_ShapeEnum aType);
53 static
54   void PointProperties(const TopoDS_Shape& aS,
55                        GProp_GProps& aGProps);
56
57 //=======================================================================
58 //function : CheckGProps
59 //purpose  :
60 //=======================================================================
61 void GEOMAlgo_GetInPlace::CheckGProps()
62 {
63   myFound=Standard_True;
64   CheckGProps(myArgument);
65 }
66 //=======================================================================
67 //function : CheckGProps
68 //purpose  :
69 //=======================================================================
70 Standard_Integer GEOMAlgo_GetInPlace::CheckGProps(const TopoDS_Shape& theS)
71 {
72   TopAbs_ShapeEnum aType = theS.ShapeType();
73
74   if (aType == TopAbs_COMPOUND) {
75     TopoDS_Iterator anIt(theS);
76     TopTools_MapOfShape aMapInc;
77
78     for(; anIt.More(); anIt.Next()) {
79       const TopoDS_Shape &aS1x = anIt.Value();
80
81       aType = aS1x.ShapeType();
82
83       if (aType != TopAbs_COMPOUND && myShapesInclusive.IsBound(aS1x)) {
84         // This is a part of a whole.
85         aMapInc.Add(aS1x);
86       } else {
87         // Check this subshape.
88         const Standard_Integer iFound = CheckGProps(aS1x);
89         
90         if (!iFound) {
91           UpdateChecked(theS, 0);
92           myFound = Standard_False;
93           return 0;
94         }
95       }
96     }
97
98     // Treat parts of a whole.
99     while (!aMapInc.IsEmpty()) {
100       TopTools_MapIteratorOfMapOfShape aMapIt(aMapInc);
101       const TopoDS_Shape &aWhole = myShapesInclusive.Find(aMapIt.Key());
102
103       if (!myImages.IsBound(aWhole)) {
104         // Should not be.
105         UpdateChecked(theS, 0);
106         myFound = Standard_False;
107         return 0;
108       }
109
110       const TopTools_ListOfShape& aLS1 = myImages.Find(aWhole);
111
112       if (aLS1.IsEmpty()) {
113         // Empty list of parts. Should not be.
114         UpdateChecked(theS, 0);
115         myFound = Standard_False;
116         return 0;
117       }
118
119       TopTools_ListIteratorOfListOfShape aItS1x(aLS1);
120
121       for (; aItS1x.More(); aItS1x.Next()) {
122         const TopoDS_Shape &aS1x = aItS1x.Value();
123
124         if (!aMapInc.Remove(aS1x)) {
125           // There is no aS1x in theS. Should not be.
126           UpdateChecked(theS, 0);
127           myFound = Standard_False;
128           return 0;
129         }
130       }
131
132       // Compare a shape with an image.
133       if (!CompareGProps(aWhole, aLS1)) {
134         // Image doesn't correspond to the shape.
135         UpdateChecked(theS, 0);
136         myFound = Standard_False;
137         return 0;
138       }
139     }
140
141     return myFound ? 1 : 0;
142   }
143
144   // Check the simple shape.
145   if (!myImages.IsBound(theS)) {
146     // it should not be.
147     UpdateChecked(theS, 0);
148     myFound = Standard_False;
149     return 0;
150   }
151   //
152   const TopTools_ListOfShape &aLS2 = myImages.Find(theS);
153
154   if (aLS2.IsEmpty()) {
155     // it should not be.
156     UpdateChecked(theS, 0);
157     myFound = Standard_False;
158     return 0;
159   }
160
161   // Compare a shape with an image.
162   if (!CompareGProps(theS, aLS2)) {
163     // Image doesn't correspond to the shape.
164     UpdateChecked(theS, 0);
165     myFound = Standard_False;
166     return 0;
167   }
168
169   UpdateChecked(theS, 1);
170   //
171   return 1;
172 }
173
174 //=======================================================================
175 //function : CompareGProps
176 //purpose  : 
177 //=======================================================================
178 Standard_Boolean GEOMAlgo_GetInPlace::CompareGProps
179                         (const TopoDS_Shape         &theShape1,
180                          const TopTools_ListOfShape &theListShape2) const
181 {
182   Standard_Boolean                   aResult = Standard_True;
183   TopoDS_Compound                    aComp2;
184   BRep_Builder                       aBuilder;
185   TopTools_ListIteratorOfListOfShape anIt(theListShape2);
186
187   aBuilder.MakeCompound(aComp2);
188
189   for (; anIt.More(); anIt.Next()) {
190     const TopoDS_Shape &aShape2 = anIt.Value();
191
192     aBuilder.Add(aComp2, aShape2);
193   }
194
195   // Compute General Properties.
196   GProp_GProps           aG1;
197   GProp_GProps           aG2;
198   const Standard_Real    aTolCG2     = myTolCG*myTolCG;
199   Standard_Boolean       bOnlyClosed = Standard_False;
200   const TopAbs_ShapeEnum aType       = theShape1.ShapeType();
201   const Standard_Integer iDim        = Dimension(aType);
202
203   if (iDim == 0) {
204     PointProperties(theShape1, aG1);
205     PointProperties(aComp2,    aG2);
206   }
207   else if (iDim == 1) {
208     BRepGProp::LinearProperties(theShape1, aG1);
209     BRepGProp::LinearProperties(aComp2,    aG2);
210   }
211   else if (iDim == 2) {
212     BRepGProp::SurfaceProperties(theShape1, aG1);
213     BRepGProp::SurfaceProperties(aComp2,    aG2);
214   }
215   else if (iDim == 3) {
216     BRepGProp::VolumeProperties(theShape1, aG1, bOnlyClosed);
217     BRepGProp::VolumeProperties(aComp2,    aG2, bOnlyClosed);
218   } else {
219     return Standard_False;
220   }
221
222   // Compare properties.
223   const Standard_Real aMass1 = aG1.Mass();
224   const Standard_Real aMass2 = aG2.Mass();
225   const gp_Pnt        aCG1   = aG1.CentreOfMass();
226   const gp_Pnt        aCG2   = aG2.CentreOfMass();
227   Standard_Real       aDM    = fabs(aMass1 - aMass2);
228   const Standard_Real aD2    = aCG1.SquareDistance(aCG2);
229
230   if (aMass1 > myTolMass) {
231     aDM /= aMass1;
232   }
233
234   if ((aDM > myTolMass) || (aD2 > aTolCG2)) {
235     aResult = Standard_False;
236   }
237
238   return aResult;
239 }
240
241 //=======================================================================
242 //function : UpdateChecked
243 //purpose  : 
244 //=======================================================================
245 void GEOMAlgo_GetInPlace::UpdateChecked(const TopoDS_Shape& theS1,
246                                         const Standard_Integer theFlag)
247 {
248   if (myChecked.IsBound(theS1)) {
249     Standard_Integer& iChecked=myChecked.ChangeFind(theS1);
250     iChecked=theFlag;
251   }
252   else {
253     myChecked.Bind(theS1, theFlag);
254   }
255 }
256 //=======================================================================
257 //function : Dimension
258 //purpose  :
259 //=======================================================================
260 Standard_Integer Dimension(const TopAbs_ShapeEnum aType)
261 {
262   Standard_Integer iDim;
263   //
264   iDim=-1;
265   switch (aType) {
266     case TopAbs_VERTEX:
267       iDim=0;
268       break;
269     case TopAbs_EDGE:
270     case TopAbs_WIRE:
271       iDim=1;
272       break;
273     case TopAbs_FACE:
274     case TopAbs_SHELL:
275       iDim=2;
276       break;
277     case TopAbs_SOLID:
278     case TopAbs_COMPSOLID:
279       iDim=3;
280       break;
281     default:
282       break;
283   }
284   return iDim;
285 }
286 //=======================================================================
287 //class : GEOMAlgo_GProps
288 //purpose  :
289 //=======================================================================
290 class GEOMAlgo_GProps : public GProp_GProps {
291  public:
292   GEOMAlgo_GProps() : GProp_GProps() {
293   };
294   //
295   GEOMAlgo_GProps(const gp_Pnt& aPLoc) : GProp_GProps(aPLoc) {
296   };
297   //
298   ~GEOMAlgo_GProps() {
299   };
300   //
301   void SetMass(const Standard_Real aMass) {
302     dim=aMass;
303   }
304   //
305   void SetCG(const gp_Pnt& aPCG) {
306     g=aPCG;
307   }
308 };
309 //=======================================================================
310 //function : PointProperties
311 //purpose  :
312 //=======================================================================
313 void PointProperties(const TopoDS_Shape& aS, GProp_GProps& aGProps)
314 {
315   Standard_Integer i, aNbS;
316   Standard_Real aDensity;
317   gp_Pnt aPX;
318   TopTools_IndexedMapOfShape aMS;
319   //
320   aDensity=1.;
321   //
322   TopExp::MapShapes(aS, TopAbs_VERTEX, aMS);
323   aNbS=aMS.Extent();
324   for (i=1; i<=aNbS; ++i) {
325     GEOMAlgo_GProps aGPropsX;
326     //
327     const TopoDS_Vertex& aVX=*((TopoDS_Vertex*)&aMS(i));
328     aPX=BRep_Tool::Pnt(aVX);
329     aGPropsX.SetMass(1.);
330     aGPropsX.SetCG(aPX);
331     aGProps.Add(aGPropsX, aDensity);
332   }
333 }