1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // 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
26 #include <GEOMAlgo_Gluer1.ixx>
28 #include <Geom_Surface.hxx>
30 #include <TopLoc_Location.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Iterator.hxx>
37 #include <BRep_Builder.hxx>
38 #include <BRep_Tool.hxx>
42 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
43 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_DataMapOfShapeShape.hxx>
51 #include <GEOMAlgo_CoupleOfShapes.hxx>
52 #include <GEOMAlgo_PassKeyShape.hxx>
53 #include <GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx>
54 #include <GEOMAlgo_DataMapOfPassKeyShapeShape.hxx>
55 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyShapeShape.hxx>
57 //=======================================================================
58 //class : GEOMAlgo_CoupleOfInteger
60 //=======================================================================
61 class GEOMAlgo_CoupleOfInteger {
65 GEOMAlgo_CoupleOfInteger() {
70 ~GEOMAlgo_CoupleOfInteger() {
73 void SetValues(const Standard_Integer aI1,
74 const Standard_Integer aI2) {
79 void SetValue1(const Standard_Integer aI1) {
83 void SetValue2(const Standard_Integer aI1) {
87 void Values(Standard_Integer& aI1,
88 Standard_Integer& aI2) const {
93 Standard_Integer Value1()const {
97 Standard_Integer Value2()const {
102 Standard_Integer myInt1;
103 Standard_Integer myInt2;
106 //=======================================================================
109 void SortShell(const Standard_Integer ,
110 GEOMAlgo_CoupleOfInteger* );
112 void RefineSolid(const TopoDS_Shape& ,
113 const TopTools_DataMapOfShapeShape& ,
114 TopTools_DataMapOfShapeShape& );
116 void MakeFaceToReplace(const TopoDS_Face& ,
119 //=======================================================================
120 //function : GEOMAlgo_Gluer1
122 //=======================================================================
123 GEOMAlgo_Gluer1::GEOMAlgo_Gluer1()
128 //=======================================================================
131 //=======================================================================
132 GEOMAlgo_Gluer1::~GEOMAlgo_Gluer1()
135 //=======================================================================
136 //function : SetFacesToUnglue
138 //=======================================================================
139 void GEOMAlgo_Gluer1::SetFacesToUnglue(const GEOMAlgo_ListOfCoupleOfShapes& aLCS)
141 myFacesToUnglue=aLCS;
143 //=======================================================================
144 //function : FacesToUnglue
146 //=======================================================================
147 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::FacesToUnglue()const
149 return myFacesToUnglue;
151 //=======================================================================
152 //function : GluedFaces
154 //=======================================================================
155 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::GluedFaces()const
159 //=======================================================================
160 //function : RejectedFaces
162 //=======================================================================
163 const GEOMAlgo_ListOfCoupleOfShapes& GEOMAlgo_Gluer1::RejectedFaces()const
165 return myRejectedFaces;
167 //=======================================================================
170 //=======================================================================
171 void GEOMAlgo_Gluer1::Perform()
174 GEOMAlgo_Gluer::Perform();
184 //=======================================================================
185 //function : FillGluedFaces
187 //=======================================================================
188 void GEOMAlgo_Gluer1::FillGluedFaces()
192 Standard_Integer aNbIm, aNbS, i;
193 TopAbs_ShapeEnum aType;
194 TopTools_ListIteratorOfListOfShape aItLS;
195 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
196 GEOMAlgo_CoupleOfShapes aCS;
197 GEOMAlgo_PassKeyShape aPKS;
200 myGluedFaces.Clear();
202 aNbIm=myImages.Extent();
203 aItIm.Initialize(myImages);
204 for (; aItIm.More(); aItIm.Next()) {
205 const TopoDS_Shape& aSnew=aItIm.Key();
206 aType=aSnew.ShapeType();
207 if (aType!=TopAbs_FACE) {
211 const TopTools_ListOfShape& aLS=aItIm.Value();
217 TopoDS_Shape aSold[2];
218 aItLS.Initialize(aLS);
219 for (i=0; aItLS.More(); aItLS.Next(), ++i) {
220 const TopoDS_Shape& aSi=aItLS.Value();
221 aSold[i]=aItLS.Value();
224 aCS.SetShapes(aSold[0], aSold[1]);
225 myGluedFaces.Append(aCS);
228 aPKS.SetShapes(aSold[0], aSold[1]);
229 myMapGN.Bind(aPKS, aSnew);
232 //=======================================================================
233 //function : UnglueFaces
235 //=======================================================================
236 void GEOMAlgo_Gluer1::UnglueFaces()
242 Standard_Boolean bFound;
243 Standard_Integer i, aNbUN, aNbS, aNbF, iX;
244 TopTools_IndexedDataMapOfShapeListOfShape aMFSR, aMFS, aMSF;
245 TopTools_ListIteratorOfListOfShape aItLS, aItLS1;
246 GEOMAlgo_PassKeyShape aPKS;
247 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
248 GEOMAlgo_DataMapOfPassKeyShapeShape aMapUN;
249 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyShapeShape aItUN;
250 GEOMAlgo_CoupleOfInteger *pIx;
252 if (myResult.IsNull()) {
253 myErrorStatus=200; // no result
257 myRejectedFaces.Clear();
259 // 0. Fill map [Face]/Solid for myResult: aMFSR
260 TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, TopAbs_SOLID, aMFSR);
262 // 1. Fill Faces to process: aMapUN : [Fold1, Fold2] / Fnew
263 aNbUN=myFacesToUnglue.Extent();
265 // all faces that can be unglued will be unglued
267 myFacesToUnglue=myGluedFaces;
270 aItCS.Initialize(myFacesToUnglue);
271 for (; aItCS.More(); aItCS.Next()) {
272 const GEOMAlgo_CoupleOfShapes& aCS=aItCS.Value();
273 const TopoDS_Shape& aS1=aCS.Shape1();
274 const TopoDS_Shape& aS2=aCS.Shape2();
276 aPKS.SetShapes(aS1, aS2);
277 if (!myMapGN.IsBound(aPKS)) {
278 //some faces, wanted to unglue, are not glued at all;
280 myRejectedFaces.Append(aCS);
284 const TopoDS_Shape& aFN=myMapGN.Find(aPKS);
285 aMapUN.Bind(aPKS, aFN);
289 // 2 Fill map FN/Solids for myResult: aMFS
290 aNbUN=aMapUN.Extent();
291 aItUN.Initialize(aMapUN);
292 for (; aItUN.More(); aItUN.Next()) {
293 const TopoDS_Shape& aFN=aItUN.Value();
294 if (!aMFSR.Contains(aFN)) {
295 myWarningStatus=3; // how can it be
299 const TopTools_ListOfShape& aLS=aMFSR.FindFromKey(aFN);
302 // wrong result: More than 2 solids shared one face
309 // 3 Fill map Solids/FN for myResult: aMSF
311 for (i=1; i<=aNbUN; ++i) {
312 const TopoDS_Shape& aFN=aMFS.FindKey(i);
313 const TopTools_ListOfShape& aLS=aMFS(i);
314 aItLS.Initialize(aLS);
315 for (; aItLS.More(); aItLS.Next()) {
316 const TopoDS_Shape& aS=aItLS.Value();
317 if (aMSF.Contains(aS)) {
318 TopTools_ListOfShape& aLF=aMSF.ChangeFromKey(aS);
322 TopTools_ListOfShape aLF;
329 // 4 Sort indices of aMSF
332 // wrong number of solids that have shared face
336 pIx=new GEOMAlgo_CoupleOfInteger[aNbS];
338 for (i=1; i<=aNbS; ++i) {
339 const TopTools_ListOfShape& aLF=aMSF(i);
341 pIx[i-1].SetValues(aNbF, i);
343 SortShell(aNbS, pIx);
347 TopTools_DataMapOfShapeShape aMFNFN2, aMFNFD;
348 TopTools_DataMapIteratorOfDataMapOfShapeShape aItMSS;
349 TopTools_MapOfShape aMFNP;
350 TopTools_IndexedMapOfShape aMFD;
352 for (iX=aNbS-1; iX>=0; --iX) {
354 // solid from myResult aSN
355 const TopoDS_Shape& aSN=aMSF.FindKey(i);
357 // candidates to be faces to replace for aSN
358 const TopTools_ListOfShape& aLFN=aMSF(i);
361 // original solid for aSN -> aSD
362 const TopTools_ListOfShape& aLSD=myImages.Find(aSN);
363 const TopoDS_Shape& aSD=aLSD.First();
365 // faces of original solid -> aMFD
367 TopExp::MapShapes(aSD, TopAbs_FACE, aMFD);
369 // faces to replace for aSN [FN]/FD -> aMFNFD
371 aItLS.Initialize(aLFN);
372 for (; aItLS.More(); aItLS.Next()) {
373 const TopoDS_Shape& aFN=aItLS.Value();
374 if (!aMFNP.Add(aFN)) {
378 // original face from original solid -> FD
381 bFound=Standard_False;
382 const TopTools_ListOfShape& aLFD=myImages.Find(aFN);
383 aItLS1.Initialize(aLFD);
384 for (; aItLS1.More(); aItLS1.Next()) {
385 const TopoDS_Shape& aFDx=aItLS1.Value();
386 if (aMFD.Contains(aFDx)) {
388 bFound=Standard_True;
393 aMFNFD.Bind(aFN, aFD);
394 } // for (; aItLS.More(); aItLS.Next()) {
396 aNbF=aMFNFD.Extent();
398 // nothing to do here
401 // update solid SN (and its shells)
402 RefineSolid(aSN, aMFNFD, aMFNFN2);
404 // update myOrigins / myImages
405 aItMSS.Initialize(aMFNFD);
406 for (; aItMSS.More(); aItMSS.Next()) {
407 const TopoDS_Shape& aFN=aItMSS.Key(); // face removed from aSN
408 const TopoDS_Shape& aFD=aItMSS.Value(); // old face from aSD
409 const TopoDS_Shape& aFN2=aMFNFN2.Find(aFN);// face added to aSN
412 myOrigins.ChangeFind(aFD)=aFN2;
415 TopTools_ListOfShape aLFDx;
417 TopTools_ListOfShape& aLFD=myImages.ChangeFind(aFN);
418 aItLS.Initialize(aLFD);
419 for (; aItLS.More(); aItLS.Next()) {
420 const TopoDS_Shape& aFDx=aItLS.Value();
421 if (!aFDx.IsSame(aFD)) {
429 myImages.Bind(aFN2, aLFDx);
430 } // for (; aItMSS.More(); aItMSS.Next()) {
431 } // for (iX=aNbS-1; iX>=0; --iX) {
435 //=======================================================================
436 // function: RefineSolid
437 // purpose : replace faces (aMFN) of solid aSd by new ones
438 //=======================================================================
439 void RefineSolid(const TopoDS_Shape& aSd,
440 const TopTools_DataMapOfShapeShape& aMFNFD,
441 TopTools_DataMapOfShapeShape& aMFNFN2)
445 TopoDS_Iterator aItSd, aItSh;
447 TopTools_ListOfShape aLF;
448 TopTools_ListIteratorOfListOfShape aItLF;
450 aItSd.Initialize(aSd);
451 for (; aItSd.More(); aItSd.Next()) {
452 const TopoDS_Shape& aSh=aItSd.Value();
453 pSh=(TopoDS_Shape *)&aSh;
454 pSh->Free(Standard_True);
456 aItSh.Initialize(*pSh);
457 for (; aItSh.More(); aItSh.Next()) {
458 const TopoDS_Shape& aF=aItSh.Value();
459 if (aMFNFD.IsBound(aF)) {
464 aItLF.Initialize(aLF);
465 for (; aItLF.More(); aItLF.Next()) {
466 const TopoDS_Face& aF=TopoDS::Face(aItLF.Value());
468 MakeFaceToReplace(aF, aF2);
470 aMFNFN2.Bind(aF, aF2);
471 aBB.Remove(*pSh, aF);
474 pSh->Free(Standard_False);
477 //=======================================================================
478 //function : MakeFaceToReplace
480 //=======================================================================
481 void MakeFaceToReplace(const TopoDS_Face& aF,
485 Handle(Geom_Surface) aS;
486 TopLoc_Location aLoc;
487 TopoDS_Face aFFWD, aFnew;
488 TopoDS_Iterator aItF;
492 aFFWD.Orientation(TopAbs_FORWARD);
493 aS=BRep_Tool::Surface(aFFWD, aLoc);
494 aTol=BRep_Tool::Tolerance(aFFWD);
496 aBB.MakeFace (aFnew, aS, aLoc, aTol);
497 aItF.Initialize(aFFWD);
498 for (; aItF.More(); aItF.Next()) {
499 const TopoDS_Shape& aW=aItF.Value();
502 aFnew.Orientation(aF.Orientation());
505 //=======================================================================
506 // function: SortShell
508 //=======================================================================
509 void SortShell(const Standard_Integer n,
510 GEOMAlgo_CoupleOfInteger* a)
512 Standard_Integer nd, i, j, l, d=1;
513 GEOMAlgo_CoupleOfInteger x;
523 for (i=0; i<nd; ++i) {
527 if (a[l].Value1() < a[j].Value1()) {
536 }//for (i=0; i<nd; ++i)
542 // 200; - result shape is Null