1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: GEOMAlgo_Gluer1.cxx
21 // Created: Wed Jan 24 11:52:27 2007
22 // Author: Peter KURNEV
25 #include <GEOMAlgo_Gluer1.ixx>
27 #include <Geom_Surface.hxx>
29 #include <TopLoc_Location.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Iterator.hxx>
36 #include <BRep_Builder.hxx>
37 #include <BRep_Tool.hxx>
41 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
42 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
43 #include <TopTools_ListOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 #include <TopTools_DataMapOfShapeShape.hxx>
50 #include <GEOMAlgo_CoupleOfShapes.hxx>
51 #include <GEOMAlgo_PassKeyShape.hxx>
52 #include <GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx>
53 #include <GEOMAlgo_DataMapOfPassKeyShapeShape.hxx>
54 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyShapeShape.hxx>
56 //=======================================================================
57 //class : GEOMAlgo_CoupleOfInteger
59 //=======================================================================
60 class GEOMAlgo_CoupleOfInteger {
64 GEOMAlgo_CoupleOfInteger() {
69 ~GEOMAlgo_CoupleOfInteger() {
72 void SetValues(const Standard_Integer aI1,
73 const Standard_Integer aI2) {
78 void SetValue1(const Standard_Integer aI1) {
82 void SetValue2(const Standard_Integer aI1) {
86 void Values(Standard_Integer& aI1,
87 Standard_Integer& aI2) const {
92 Standard_Integer Value1()const {
96 Standard_Integer Value2()const {
101 Standard_Integer myInt1;
102 Standard_Integer myInt2;
105 //=======================================================================
108 void SortShell(const Standard_Integer ,
109 GEOMAlgo_CoupleOfInteger* );
111 void RefineSolid(const TopoDS_Shape& ,
112 const TopTools_DataMapOfShapeShape& ,
113 TopTools_DataMapOfShapeShape& );
115 void MakeFaceToReplace(const TopoDS_Face& ,
118 //=======================================================================
119 //function : GEOMAlgo_Gluer1
121 //=======================================================================
122 GEOMAlgo_Gluer1::GEOMAlgo_Gluer1()
127 //=======================================================================
130 //=======================================================================
131 GEOMAlgo_Gluer1::~GEOMAlgo_Gluer1()
134 //=======================================================================
135 //function : SetFacesToUnglue
137 //=======================================================================
138 void GEOMAlgo_Gluer1::SetFacesToUnglue(const GEOMAlgo_ListOfCoupleOfShapes& aLCS)
140 myFacesToUnglue=aLCS;
142 //=======================================================================
143 //function : FacesToUnglue
145 //=======================================================================
146 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::FacesToUnglue()const
148 return myFacesToUnglue;
150 //=======================================================================
151 //function : GluedFaces
153 //=======================================================================
154 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::GluedFaces()const
158 //=======================================================================
159 //function : RejectedFaces
161 //=======================================================================
162 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::RejectedFaces()const
164 return myRejectedFaces;
166 //=======================================================================
169 //=======================================================================
170 void GEOMAlgo_Gluer1::Perform()
173 GEOMAlgo_Gluer::Perform();
183 //=======================================================================
184 //function : FillGluedFaces
186 //=======================================================================
187 void GEOMAlgo_Gluer1::FillGluedFaces()
191 Standard_Integer aNbIm, aNbS, i;
192 TopAbs_ShapeEnum aType;
193 TopTools_ListIteratorOfListOfShape aItLS;
194 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
195 GEOMAlgo_CoupleOfShapes aCS;
196 GEOMAlgo_PassKeyShape aPKS;
199 myGluedFaces.Clear();
201 aNbIm=myImages.Extent();
202 aItIm.Initialize(myImages);
203 for (; aItIm.More(); aItIm.Next()) {
204 const TopoDS_Shape& aSnew=aItIm.Key();
205 aType=aSnew.ShapeType();
206 if (aType!=TopAbs_FACE) {
210 const TopTools_ListOfShape& aLS=aItIm.Value();
216 TopoDS_Shape aSold[2];
217 aItLS.Initialize(aLS);
218 for (i=0; aItLS.More(); aItLS.Next(), ++i) {
219 const TopoDS_Shape& aSi=aItLS.Value();
220 aSold[i]=aItLS.Value();
223 aCS.SetShapes(aSold[0], aSold[1]);
224 myGluedFaces.Append(aCS);
227 aPKS.SetShapes(aSold[0], aSold[1]);
228 myMapGN.Bind(aPKS, aSnew);
231 //=======================================================================
232 //function : UnglueFaces
234 //=======================================================================
235 void GEOMAlgo_Gluer1::UnglueFaces()
241 Standard_Boolean bFound;
242 Standard_Integer i, aNbUN, aNbS, aNbF, iX;
243 TopTools_IndexedDataMapOfShapeListOfShape aMFSR, aMFS, aMSF;
244 TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
245 GEOMAlgo_PassKeyShape aPKS;
246 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
247 GEOMAlgo_DataMapOfPassKeyShapeShape aMapUN;
248 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyShapeShape aItUN;
249 GEOMAlgo_CoupleOfInteger *pIx;
251 if (myResult.IsNull()) {
252 myErrorStatus=200; // no result
256 myRejectedFaces.Clear();
258 // 0. Fill map [Face]/Solid for myResult: aMFSR
259 TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, TopAbs_SOLID, aMFSR);
261 // 1. Fill Faces to process: aMapUN : [Fold1, Fold2] / Fnew
262 aNbUN=myFacesToUnglue.Extent();
264 // all faces that can be unglued will be unglued
266 myFacesToUnglue=myGluedFaces;
269 aItCS.Initialize(myFacesToUnglue);
270 for (; aItCS.More(); aItCS.Next()) {
271 const GEOMAlgo_CoupleOfShapes& aCS=aItCS.Value();
272 const TopoDS_Shape& aS1=aCS.Shape1();
273 const TopoDS_Shape& aS2=aCS.Shape2();
275 aPKS.SetShapes(aS1, aS2);
276 if (!myMapGN.IsBound(aPKS)) {
277 //some faces, wanted to unglue, are not glued at all;
279 myRejectedFaces.Append(aCS);
283 const TopoDS_Shape& aFN=myMapGN.Find(aPKS);
284 aMapUN.Bind(aPKS, aFN);
288 // 2 Fill map FN/Solids for myResult: aMFS
289 aNbUN=aMapUN.Extent();
290 aItUN.Initialize(aMapUN);
291 for (; aItUN.More(); aItUN.Next()) {
292 const TopoDS_Shape& aFN=aItUN.Value();
293 if (!aMFSR.Contains(aFN)) {
294 myWarningStatus=3; // how can it be
298 const TopTools_ListOfShape& aLS=aMFSR.FindFromKey(aFN);
301 // wrong result: More than 2 solids shared one face
308 // 3 Fill map Solids/FN for myResult: aMSF
310 for (i=1; i<=aNbUN; ++i) {
311 const TopoDS_Shape& aFN=aMFS.FindKey(i);
312 const TopTools_ListOfShape& aLS=aMFS(i);
313 aItLS.Initialize(aLS);
314 for (; aItLS.More(); aItLS.Next()) {
315 const TopoDS_Shape& aS=aItLS.Value();
316 if (aMSF.Contains(aS)) {
317 TopTools_ListOfShape& aLF=aMSF.ChangeFromKey(aS);
321 TopTools_ListOfShape aLF;
328 // 4 Sort indices of aMSF
331 // wrong number of solids that have shared face
335 pIx=new GEOMAlgo_CoupleOfInteger[aNbS];
337 for (i=1; i<=aNbS; ++i) {
338 const TopTools_ListOfShape& aLF=aMSF(i);
340 pIx[i-1].SetValues(aNbF, i);
342 SortShell(aNbS, pIx);
346 TopTools_DataMapOfShapeShape aMFNFN2, aMFNFD;
347 TopTools_DataMapIteratorOfDataMapOfShapeShape aItMSS;
348 TopTools_MapOfShape aMFNP;
349 TopTools_IndexedMapOfShape aMFD;
351 for (iX=aNbS-1; iX>=0; --iX) {
353 // solid from myResult aSN
354 const TopoDS_Shape& aSN=aMSF.FindKey(i);
356 // candidates to be faces to replace for aSN
357 const TopTools_ListOfShape& aLFN=aMSF(i);
360 // original solid for aSN -> aSD
361 const TopTools_ListOfShape& aLSD=myImages.Find(aSN);
362 const TopoDS_Shape& aSD=aLSD.First();
364 // faces of original solid -> aMFD
366 TopExp::MapShapes(aSD, TopAbs_FACE, aMFD);
368 // faces to replace for aSN [FN]/FD -> aMFNFD
370 aItLS.Initialize(aLFN);
371 for (; aItLS.More(); aItLS.Next()) {
372 const TopoDS_Shape& aFN=aItLS.Value();
373 if (!aMFNP.Add(aFN)) {
377 // original face from original solid -> FD
380 bFound=Standard_False;
381 const TopTools_ListOfShape& aLFD=myImages.Find(aFN);
382 aItLS1.Initialize(aLFD);
383 for (; aItLS1.More(); aItLS1.Next()) {
384 const TopoDS_Shape& aFDx=aItLS1.Value();
385 if (aMFD.Contains(aFDx)) {
387 bFound=Standard_True;
392 aMFNFD.Bind(aFN, aFD);
393 } // for (; aItLS.More(); aItLS.Next()) {
395 aNbF=aMFNFD.Extent();
397 // nothing to do here
400 // update solid SN (and its shells)
401 RefineSolid(aSN, aMFNFD, aMFNFN2);
403 // update myOrigins / myImages
404 aItMSS.Initialize(aMFNFD);
405 for (; aItMSS.More(); aItMSS.Next()) {
406 const TopoDS_Shape& aFN=aItMSS.Key(); // face removed from aSN
407 const TopoDS_Shape& aFD=aItMSS.Value(); // old face from aSD
408 const TopoDS_Shape& aFN2=aMFNFN2.Find(aFN);// face added to aSN
411 myOrigins.ChangeFind(aFD)=aFN2;
414 TopTools_ListOfShape aLFDx;
416 TopTools_ListOfShape& aLFD=myImages.ChangeFind(aFN);
417 aItLS.Initialize(aLFD);
418 for (; aItLS.More(); aItLS.Next()) {
419 const TopoDS_Shape& aFDx=aItLS.Value();
420 if (!aFDx.IsSame(aFD)) {
428 myImages.Bind(aFN2, aLFDx);
429 } // for (; aItMSS.More(); aItMSS.Next()) {
430 } // for (iX=aNbS-1; iX>=0; --iX) {
434 //=======================================================================
435 // function: RefineSolid
436 // purpose : replace faces (aMFN) of solid aSd by new ones
437 //=======================================================================
438 void RefineSolid(const TopoDS_Shape& aSd,
439 const TopTools_DataMapOfShapeShape& aMFNFD,
440 TopTools_DataMapOfShapeShape& aMFNFN2)
444 TopoDS_Iterator aItSd, aItSh;
446 TopTools_ListOfShape aLF;
447 TopTools_ListIteratorOfListOfShape aItLF;
449 aItSd.Initialize(aSd);
450 for (; aItSd.More(); aItSd.Next()) {
451 const TopoDS_Shape& aSh=aItSd.Value();
452 pSh=(TopoDS_Shape *)&aSh;
453 pSh->Free(Standard_True);
455 aItSh.Initialize(*pSh);
456 for (; aItSh.More(); aItSh.Next()) {
457 const TopoDS_Shape& aF=aItSh.Value();
458 if (aMFNFD.IsBound(aF)) {
463 aItLF.Initialize(aLF);
464 for (; aItLF.More(); aItLF.Next()) {
465 const TopoDS_Face& aF=TopoDS::Face(aItLF.Value());
467 MakeFaceToReplace(aF, aF2);
469 aMFNFN2.Bind(aF, aF2);
470 aBB.Remove(*pSh, aF);
473 pSh->Free(Standard_False);
476 //=======================================================================
477 //function : MakeFaceToReplace
479 //=======================================================================
480 void MakeFaceToReplace(const TopoDS_Face& aF,
484 Handle(Geom_Surface) aS;
485 TopLoc_Location aLoc;
486 TopoDS_Face aFFWD, aFnew;
487 TopoDS_Iterator aItF;
491 aFFWD.Orientation(TopAbs_FORWARD);
492 aS=BRep_Tool::Surface(aFFWD, aLoc);
493 aTol=BRep_Tool::Tolerance(aFFWD);
495 aBB.MakeFace (aFnew, aS, aLoc, aTol);
496 aItF.Initialize(aFFWD);
497 for (; aItF.More(); aItF.Next()) {
498 const TopoDS_Shape& aW=aItF.Value();
501 aFnew.Orientation(aF.Orientation());
504 //=======================================================================
505 // function: SortShell
507 //=======================================================================
508 void SortShell(const Standard_Integer n,
509 GEOMAlgo_CoupleOfInteger* a)
511 Standard_Integer nd, i, j, l, d=1;
512 GEOMAlgo_CoupleOfInteger x;
522 for (i=0; i<nd; ++i) {
526 if (a[l].Value1() < a[j].Value1()) {
535 }//for (i=0; i<nd; ++i)
541 // 200; - result shape is Null