1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: GEOMAlgo_Gluer1.cxx
23 // Created: Wed Jan 24 11:52:27 2007
24 // Author: Peter KURNEV
27 #include <GEOMAlgo_Gluer1.ixx>
29 #include <Geom_Surface.hxx>
31 #include <TopLoc_Location.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Face.hxx>
36 #include <TopoDS_Iterator.hxx>
38 #include <BRep_Builder.hxx>
39 #include <BRep_Tool.hxx>
43 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
44 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
45 #include <TopTools_ListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_MapOfShape.hxx>
50 #include <TopTools_DataMapOfShapeShape.hxx>
52 #include <GEOMAlgo_CoupleOfShapes.hxx>
53 #include <GEOMAlgo_PassKeyShape.hxx>
54 #include <GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx>
55 #include <GEOMAlgo_DataMapOfPassKeyShapeShape.hxx>
56 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyShapeShape.hxx>
58 //=======================================================================
59 //class : GEOMAlgo_CoupleOfInteger
61 //=======================================================================
62 class GEOMAlgo_CoupleOfInteger {
66 GEOMAlgo_CoupleOfInteger() {
71 ~GEOMAlgo_CoupleOfInteger() {
74 void SetValues(const Standard_Integer aI1,
75 const Standard_Integer aI2) {
80 void SetValue1(const Standard_Integer aI1) {
84 void SetValue2(const Standard_Integer aI1) {
88 void Values(Standard_Integer& aI1,
89 Standard_Integer& aI2) const {
94 Standard_Integer Value1()const {
98 Standard_Integer Value2()const {
103 Standard_Integer myInt1;
104 Standard_Integer myInt2;
107 //=======================================================================
110 void SortShell(const Standard_Integer ,
111 GEOMAlgo_CoupleOfInteger* );
113 void RefineSolid(const TopoDS_Shape& ,
114 const TopTools_DataMapOfShapeShape& ,
115 TopTools_DataMapOfShapeShape& );
117 void MakeFaceToReplace(const TopoDS_Face& ,
120 //=======================================================================
121 //function : GEOMAlgo_Gluer1
123 //=======================================================================
124 GEOMAlgo_Gluer1::GEOMAlgo_Gluer1()
129 //=======================================================================
132 //=======================================================================
133 GEOMAlgo_Gluer1::~GEOMAlgo_Gluer1()
136 //=======================================================================
137 //function : SetFacesToUnglue
139 //=======================================================================
140 void GEOMAlgo_Gluer1::SetFacesToUnglue(const GEOMAlgo_ListOfCoupleOfShapes& aLCS)
142 myFacesToUnglue=aLCS;
144 //=======================================================================
145 //function : FacesToUnglue
147 //=======================================================================
148 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::FacesToUnglue()const
150 return myFacesToUnglue;
152 //=======================================================================
153 //function : GluedFaces
155 //=======================================================================
156 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::GluedFaces()const
160 //=======================================================================
161 //function : RejectedFaces
163 //=======================================================================
164 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::RejectedFaces()const
166 return myRejectedFaces;
168 //=======================================================================
171 //=======================================================================
172 void GEOMAlgo_Gluer1::Perform()
175 GEOMAlgo_Gluer::Perform();
185 //=======================================================================
186 //function : FillGluedFaces
188 //=======================================================================
189 void GEOMAlgo_Gluer1::FillGluedFaces()
193 Standard_Integer aNbIm, aNbS, i;
194 TopAbs_ShapeEnum aType;
195 TopTools_ListIteratorOfListOfShape aItLS;
196 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
197 GEOMAlgo_CoupleOfShapes aCS;
198 GEOMAlgo_PassKeyShape aPKS;
201 myGluedFaces.Clear();
203 aNbIm=myImages.Extent();
204 aItIm.Initialize(myImages);
205 for (; aItIm.More(); aItIm.Next()) {
206 const TopoDS_Shape& aSnew=aItIm.Key();
207 aType=aSnew.ShapeType();
208 if (aType!=TopAbs_FACE) {
212 const TopTools_ListOfShape& aLS=aItIm.Value();
218 TopoDS_Shape aSold[2];
219 aItLS.Initialize(aLS);
220 for (i=0; aItLS.More(); aItLS.Next(), ++i) {
221 const TopoDS_Shape& aSi=aItLS.Value();
222 aSold[i]=aItLS.Value();
225 aCS.SetShapes(aSold[0], aSold[1]);
226 myGluedFaces.Append(aCS);
229 aPKS.SetShapes(aSold[0], aSold[1]);
230 myMapGN.Bind(aPKS, aSnew);
233 //=======================================================================
234 //function : UnglueFaces
236 //=======================================================================
237 void GEOMAlgo_Gluer1::UnglueFaces()
243 Standard_Boolean bFound;
244 Standard_Integer i, aNbUN, aNbS, aNbF, iX;
245 TopTools_IndexedDataMapOfShapeListOfShape aMFSR, aMFS, aMSF;
246 TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
247 GEOMAlgo_PassKeyShape aPKS;
248 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
249 GEOMAlgo_DataMapOfPassKeyShapeShape aMapUN;
250 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyShapeShape aItUN;
251 GEOMAlgo_CoupleOfInteger *pIx;
253 if (myResult.IsNull()) {
254 myErrorStatus=200; // no result
258 myRejectedFaces.Clear();
260 // 0. Fill map [Face]/Solid for myResult: aMFSR
261 TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, TopAbs_SOLID, aMFSR);
263 // 1. Fill Faces to process: aMapUN : [Fold1, Fold2] / Fnew
264 aNbUN=myFacesToUnglue.Extent();
266 // all faces that can be unglued will be unglued
268 myFacesToUnglue=myGluedFaces;
271 aItCS.Initialize(myFacesToUnglue);
272 for (; aItCS.More(); aItCS.Next()) {
273 const GEOMAlgo_CoupleOfShapes& aCS=aItCS.Value();
274 const TopoDS_Shape& aS1=aCS.Shape1();
275 const TopoDS_Shape& aS2=aCS.Shape2();
277 aPKS.SetShapes(aS1, aS2);
278 if (!myMapGN.IsBound(aPKS)) {
279 //some faces, wanted to unglue, are not glued at all;
281 myRejectedFaces.Append(aCS);
285 const TopoDS_Shape& aFN=myMapGN.Find(aPKS);
286 aMapUN.Bind(aPKS, aFN);
290 // 2 Fill map FN/Solids for myResult: aMFS
291 aNbUN=aMapUN.Extent();
292 aItUN.Initialize(aMapUN);
293 for (; aItUN.More(); aItUN.Next()) {
294 const TopoDS_Shape& aFN=aItUN.Value();
295 if (!aMFSR.Contains(aFN)) {
296 myWarningStatus=3; // how can it be
300 const TopTools_ListOfShape& aLS=aMFSR.FindFromKey(aFN);
303 // wrong result: More than 2 solids shared one face
310 // 3 Fill map Solids/FN for myResult: aMSF
312 for (i=1; i<=aNbUN; ++i) {
313 const TopoDS_Shape& aFN=aMFS.FindKey(i);
314 const TopTools_ListOfShape& aLS=aMFS(i);
315 aItLS.Initialize(aLS);
316 for (; aItLS.More(); aItLS.Next()) {
317 const TopoDS_Shape& aS=aItLS.Value();
318 if (aMSF.Contains(aS)) {
319 TopTools_ListOfShape& aLF=aMSF.ChangeFromKey(aS);
323 TopTools_ListOfShape aLF;
330 // 4 Sort indices of aMSF
333 // wrong number of solids that have shared face
337 pIx=new GEOMAlgo_CoupleOfInteger[aNbS];
339 for (i=1; i<=aNbS; ++i) {
340 const TopTools_ListOfShape& aLF=aMSF(i);
342 pIx[i-1].SetValues(aNbF, i);
344 SortShell(aNbS, pIx);
348 TopTools_DataMapOfShapeShape aMFNFN2, aMFNFD;
349 TopTools_DataMapIteratorOfDataMapOfShapeShape aItMSS;
350 TopTools_MapOfShape aMFNP;
351 TopTools_IndexedMapOfShape aMFD;
353 for (iX=aNbS-1; iX>=0; --iX) {
355 // solid from myResult aSN
356 const TopoDS_Shape& aSN=aMSF.FindKey(i);
358 // candidates to be faces to replace for aSN
359 const TopTools_ListOfShape& aLFN=aMSF(i);
362 // original solid for aSN -> aSD
363 const TopTools_ListOfShape& aLSD=myImages.Find(aSN);
364 const TopoDS_Shape& aSD=aLSD.First();
366 // faces of original solid -> aMFD
368 TopExp::MapShapes(aSD, TopAbs_FACE, aMFD);
370 // faces to replace for aSN [FN]/FD -> aMFNFD
372 aItLS.Initialize(aLFN);
373 for (; aItLS.More(); aItLS.Next()) {
374 const TopoDS_Shape& aFN=aItLS.Value();
375 if (!aMFNP.Add(aFN)) {
379 // original face from original solid -> FD
382 bFound=Standard_False;
383 const TopTools_ListOfShape& aLFD=myImages.Find(aFN);
384 aItLS1.Initialize(aLFD);
385 for (; aItLS1.More(); aItLS1.Next()) {
386 const TopoDS_Shape& aFDx=aItLS1.Value();
387 if (aMFD.Contains(aFDx)) {
389 bFound=Standard_True;
394 aMFNFD.Bind(aFN, aFD);
395 } // for (; aItLS.More(); aItLS.Next()) {
397 aNbF=aMFNFD.Extent();
399 // nothing to do here
402 // update solid SN (and its shells)
403 RefineSolid(aSN, aMFNFD, aMFNFN2);
405 // update myOrigins / myImages
406 aItMSS.Initialize(aMFNFD);
407 for (; aItMSS.More(); aItMSS.Next()) {
408 const TopoDS_Shape& aFN=aItMSS.Key(); // face removed from aSN
409 const TopoDS_Shape& aFD=aItMSS.Value(); // old face from aSD
410 const TopoDS_Shape& aFN2=aMFNFN2.Find(aFN);// face added to aSN
413 myOrigins.ChangeFind(aFD)=aFN2;
416 TopTools_ListOfShape aLFDx;
418 TopTools_ListOfShape& aLFD=myImages.ChangeFind(aFN);
419 aItLS.Initialize(aLFD);
420 for (; aItLS.More(); aItLS.Next()) {
421 const TopoDS_Shape& aFDx=aItLS.Value();
422 if (!aFDx.IsSame(aFD)) {
430 myImages.Bind(aFN2, aLFDx);
431 } // for (; aItMSS.More(); aItMSS.Next()) {
432 } // for (iX=aNbS-1; iX>=0; --iX) {
436 //=======================================================================
437 // function: RefineSolid
438 // purpose : replace faces (aMFN) of solid aSd by new ones
439 //=======================================================================
440 void RefineSolid(const TopoDS_Shape& aSd,
441 const TopTools_DataMapOfShapeShape& aMFNFD,
442 TopTools_DataMapOfShapeShape& aMFNFN2)
446 TopoDS_Iterator aItSd, aItSh;
448 TopTools_ListOfShape aLF;
449 TopTools_ListIteratorOfListOfShape aItLF;
451 aItSd.Initialize(aSd);
452 for (; aItSd.More(); aItSd.Next()) {
453 const TopoDS_Shape& aSh=aItSd.Value();
454 pSh=(TopoDS_Shape *)&aSh;
455 pSh->Free(Standard_True);
457 aItSh.Initialize(*pSh);
458 for (; aItSh.More(); aItSh.Next()) {
459 const TopoDS_Shape& aF=aItSh.Value();
460 if (aMFNFD.IsBound(aF)) {
465 aItLF.Initialize(aLF);
466 for (; aItLF.More(); aItLF.Next()) {
467 const TopoDS_Face& aF=TopoDS::Face(aItLF.Value());
469 MakeFaceToReplace(aF, aF2);
471 aMFNFN2.Bind(aF, aF2);
472 aBB.Remove(*pSh, aF);
475 pSh->Free(Standard_False);
478 //=======================================================================
479 //function : MakeFaceToReplace
481 //=======================================================================
482 void MakeFaceToReplace(const TopoDS_Face& aF,
486 Handle(Geom_Surface) aS;
487 TopLoc_Location aLoc;
488 TopoDS_Face aFFWD, aFnew;
489 TopoDS_Iterator aItF;
493 aFFWD.Orientation(TopAbs_FORWARD);
494 aS=BRep_Tool::Surface(aFFWD, aLoc);
495 aTol=BRep_Tool::Tolerance(aFFWD);
497 aBB.MakeFace (aFnew, aS, aLoc, aTol);
498 aItF.Initialize(aFFWD);
499 for (; aItF.More(); aItF.Next()) {
500 const TopoDS_Shape& aW=aItF.Value();
503 aFnew.Orientation(aF.Orientation());
506 //=======================================================================
507 // function: SortShell
509 //=======================================================================
510 void SortShell(const Standard_Integer n,
511 GEOMAlgo_CoupleOfInteger* a)
513 Standard_Integer nd, i, j, l, d=1;
514 GEOMAlgo_CoupleOfInteger x;
524 for (i=0; i<nd; ++i) {
528 if (a[l].Value1() < a[j].Value1()) {
537 }//for (i=0; i<nd; ++i)
543 // 200; - result shape is Null