Back to index

salome-geom  6.5.0
GEOMAlgo_Gluer.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:      GEOMAlgo_Gluer.cxx
00024 // Created:   Sat Dec 04 12:45:53 2004
00025 // Author:    Peter KURNEV
00026 //            <peter@PREFEX>
00027 //
00028 #include <GEOMAlgo_Gluer.hxx>
00029 
00030 #include <NMTDS_BoxBndTree.hxx>
00031 #include <NCollection_UBTreeFiller.hxx>
00032 
00033 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
00034 #include <TColStd_MapOfInteger.hxx>
00035 #include <TColStd_ListOfInteger.hxx>
00036 #include <TColStd_ListIteratorOfListOfInteger.hxx>
00037 
00038 #include <gp_Pnt.hxx>
00039 #include <gp_Dir.hxx>
00040 #include <gp_XYZ.hxx>
00041 
00042 #include <Geom_Curve.hxx>
00043 #include <Geom_Surface.hxx>
00044 
00045 #include <Bnd_Box.hxx>
00046 #include <Bnd_HArray1OfBox.hxx>
00047 #include <Bnd_BoundSortBox.hxx>
00048 
00049 #include <TopLoc_Location.hxx>
00050 #include <TopAbs_ShapeEnum.hxx>
00051 #include <TopAbs_Orientation.hxx>
00052 
00053 #include <TopoDS.hxx>
00054 #include <TopoDS_Edge.hxx>
00055 #include <TopoDS_Vertex.hxx>
00056 #include <TopoDS_Shape.hxx>
00057 #include <TopoDS_Compound.hxx>
00058 #include <TopoDS_Wire.hxx>
00059 #include <TopoDS_Shell.hxx>
00060 #include <TopoDS_Solid.hxx>
00061 #include <TopoDS_Iterator.hxx>
00062 
00063 #include <TopTools_IndexedMapOfShape.hxx>
00064 #include <TopTools_ListOfShape.hxx>
00065 #include <TopTools_ListIteratorOfListOfShape.hxx>
00066 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
00067 #include <TopTools_MapOfShape.hxx>
00068 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00069 
00070 #include <TopExp.hxx>
00071 #include <TopExp_Explorer.hxx>
00072 
00073 #include <BRep_Tool.hxx>
00074 #include <BRep_Builder.hxx>
00075 #include <BRepLib.hxx>
00076 #include <BRepTools.hxx>
00077 #include <BRepBndLib.hxx>
00078 
00079 #include <IntTools_Context.hxx>
00080 #include <BOPTools_Tools.hxx>
00081 #include <BOPTools_Tools3D.hxx>
00082 #include <BOPTools_Tools2D.hxx>
00083 #include <BOP_CorrectTolerances.hxx>
00084 
00085 #include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
00086 #include <GEOMAlgo_IndexedDataMapOfShapeBox.hxx>
00087 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
00088 #include <GEOMAlgo_PassKeyShape.hxx>
00089 #include <GEOMAlgo_Tools.hxx>
00090 //
00091 
00092 #include <NMTDS_BndSphereTree.hxx>
00093 #include <NMTDS_BndSphere.hxx>
00094 #include <NMTDS_IndexedDataMapOfShapeBndSphere.hxx>
00095 
00096 //
00097 static
00098   void GetSubShapes(const TopoDS_Shape& aS,
00099                   TopTools_IndexedMapOfShape& aMSS);
00100 
00101 //=======================================================================
00102 //function : GEOMAlgo_Gluer
00103 //purpose  :
00104 //=======================================================================
00105 GEOMAlgo_Gluer::GEOMAlgo_Gluer()
00106 :
00107   GEOMAlgo_ShapeAlgo()
00108 {
00109   myTolerance=0.0001;
00110   myTol=myTolerance;
00111   myCheckGeometry=Standard_True;
00112   myKeepNonSolids=Standard_False;
00113   myNbAlone=0;
00114 }
00115 //=======================================================================
00116 //function : ~GEOMAlgo_Gluer
00117 //purpose  :
00118 //=======================================================================
00119 GEOMAlgo_Gluer::~GEOMAlgo_Gluer()
00120 {
00121 }
00122 //=======================================================================
00123 //function : SetCheckGeometry
00124 //purpose  :
00125 //=======================================================================
00126 void GEOMAlgo_Gluer::SetCheckGeometry(const Standard_Boolean aFlag)
00127 {
00128   myCheckGeometry=aFlag;
00129 }
00130 //=======================================================================
00131 //function : CheckGeometry
00132 //purpose  :
00133 //=======================================================================
00134 Standard_Boolean GEOMAlgo_Gluer::CheckGeometry() const
00135 {
00136   return myCheckGeometry;
00137 }
00138 //=======================================================================
00139 //function : SetKeepNonSolids
00140 //purpose  :
00141 //=======================================================================
00142 void GEOMAlgo_Gluer::SetKeepNonSolids(const Standard_Boolean aFlag)
00143 {
00144   myKeepNonSolids=aFlag;
00145 }
00146 //=======================================================================
00147 //function : KeepNonSolids
00148 //purpose  :
00149 //=======================================================================
00150 Standard_Boolean GEOMAlgo_Gluer::KeepNonSolids()const
00151 {
00152   return myKeepNonSolids;
00153 }
00154 //=======================================================================
00155 //function : AloneShapes
00156 //purpose  :
00157 //=======================================================================
00158 Standard_Integer GEOMAlgo_Gluer::AloneShapes()const
00159 {
00160   return myNbAlone;
00161 }
00162 //=======================================================================
00163 //function : Images
00164 //purpose  :
00165 //=======================================================================
00166 const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer::Images()const
00167 {
00168   return myImages;
00169 }
00170 //=======================================================================
00171 //function : Origins
00172 //purpose  :
00173 //=======================================================================
00174 const TopTools_DataMapOfShapeShape& GEOMAlgo_Gluer::Origins()const
00175 {
00176   return myOrigins;
00177 }
00178 //=======================================================================
00179 //function : Perform
00180 //purpose  :
00181 //=======================================================================
00182 void GEOMAlgo_Gluer::Perform()
00183 {
00184   const Standard_Integer aNb=8;
00185   Standard_Integer i;
00186   //
00187   myErrorStatus=0;
00188   myWarningStatus=0;
00189   //
00190   // Initialize the context
00191   GEOMAlgo_ShapeAlgo::Perform();
00192   //
00193   void (GEOMAlgo_Gluer::* pF[aNb])()={
00194     &GEOMAlgo_Gluer::CheckData,       &GEOMAlgo_Gluer::InnerTolerance,
00195     &GEOMAlgo_Gluer::MakeVertices,    &GEOMAlgo_Gluer::MakeEdges,
00196     &GEOMAlgo_Gluer::MakeFaces,       &GEOMAlgo_Gluer::MakeShells,
00197     &GEOMAlgo_Gluer::MakeSolids,      &GEOMAlgo_Gluer::CheckResult
00198   };
00199   //
00200   for (i=0; i<aNb; ++i) {
00201     (this->*pF[i])();
00202     if (myErrorStatus) {
00203       return;
00204     }
00205   }
00206 }
00207 
00208 //=======================================================================
00209 //function : MakeVertices
00210 //purpose  :
00211 //=======================================================================
00212 void GEOMAlgo_Gluer::MakeVertices()
00213 {
00214   myErrorStatus=0;
00215   //
00216   Standard_Integer j, i, aNbV, aNbVSD;
00217   Standard_Real aTolV;
00218   gp_Pnt aPV;
00219   TColStd_ListIteratorOfListOfInteger aIt;
00220   TopoDS_Shape aVF;
00221   TopoDS_Vertex aVnew;
00222   TopTools_IndexedMapOfShape aMV, aMVProcessed;
00223   TopTools_ListIteratorOfListOfShape aItS;
00224   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
00225   TopTools_DataMapOfShapeListOfShape aMVV;
00226   GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
00227   //modified by NIZNHY-PKV Thu Jan 21 10:03:07 2010f
00228   //GEOMAlgo_IndexedDataMapOfShapeBox aMSB;
00229   NMTDS_IndexedDataMapOfShapeBndSphere aMSB;
00230   //modified by NIZNHY-PKV Thu Jan 21 10:03:10 2010t
00231   //
00232   NMTDS_BndSphereTreeSelector aSelector;
00233   NMTDS_BndSphereTree aBBTree;
00234   NCollection_UBTreeFiller <Standard_Integer, NMTDS_BndSphere> aTreeFiller(aBBTree);
00235   //
00236   TopExp::MapShapes(myShape, TopAbs_VERTEX, aMV);
00237   aNbV=aMV.Extent();
00238   if (!aNbV) {
00239     myErrorStatus=2; // no vertices in source shape
00240     return;
00241   }
00242   //
00243   for (i=1; i<=aNbV; ++i) {
00244     NMTDS_BndSphere aBox;
00245     //
00246     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i));
00247     aPV=BRep_Tool::Pnt(aV);
00248     aTolV=BRep_Tool::Tolerance(aV);
00249     //
00250     aBox.SetGap(myTol);
00251     aBox.SetCenter(aPV);
00252     aBox.SetRadius(aTolV);
00253     //
00254     aTreeFiller.Add(i, aBox);
00255     //
00256     aMIS.Add(i, aV);
00257     aMSB.Add(aV, aBox);
00258   }
00259   //
00260   aTreeFiller.Fill();
00261   //
00262   //------------------------------
00263   // Chains
00264   for (i=1; i<=aNbV; ++i) {
00265     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i));
00266     //
00267     if (aMVProcessed.Contains(aV)) {
00268       continue;
00269     }
00270     //
00271     Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
00272     TopTools_ListOfShape aLVSD;
00273     TColStd_MapOfInteger aMIP, aMIP1, aMIPC;
00274     TColStd_MapIteratorOfMapOfInteger aIt1;
00275     //
00276     aMIP.Add(i);
00277     while(1) {
00278       aNbIP=aMIP.Extent();
00279       aIt1.Initialize(aMIP);
00280       for(; aIt1.More(); aIt1.Next()) {
00281        aIP=aIt1.Key();
00282        if (aMIPC.Contains(aIP)) {
00283          continue;
00284        }
00285        //
00286        const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
00287        //modified by NIZNHY-PKV Thu Jan 21 10:04:09 2010f
00288        const NMTDS_BndSphere& aBoxVP=aMSB.FindFromKey(aVP);
00289        //const Bnd_Box& aBoxVP=aMSB.FindFromKey(aVP);
00290        //modified by NIZNHY-PKV Thu Jan 21 10:04:11 2010t
00291        //
00292        aSelector.Clear();
00293        aSelector.SetBox(aBoxVP);
00294        //
00295        aNbVSD=aBBTree.Select(aSelector);
00296        if (!aNbVSD) {
00297          continue;  // it must not be
00298        }
00299        //
00300        const TColStd_ListOfInteger& aLI=aSelector.Indices();
00301        //
00302        aIt.Initialize(aLI);
00303        for (; aIt.More(); aIt.Next()) {
00304          aIP1=aIt.Value();
00305          if (aMIP.Contains(aIP1)) {
00306            continue;
00307          }
00308          aMIP1.Add(aIP1);
00309        } //for (; aIt.More(); aIt.Next()) {
00310       }//for(; aIt1.More(); aIt1.Next()) {
00311       //
00312       aNbIP1=aMIP1.Extent();
00313       if (!aNbIP1) {
00314        break;
00315       }
00316       //
00317       aIt1.Initialize(aMIP);
00318       for(; aIt1.More(); aIt1.Next()) {
00319        aIP=aIt1.Key();
00320        aMIPC.Add(aIP);
00321       }
00322       //
00323       aMIP.Clear();
00324       aIt1.Initialize(aMIP1);
00325       for(; aIt1.More(); aIt1.Next()) {
00326        aIP=aIt1.Key();
00327        aMIP.Add(aIP);
00328       }
00329       aMIP1.Clear();
00330     }// while(1)
00331     //
00332     // Fill myImages
00333     aNbIP=aMIPC.Extent();
00334     //
00335     if (!aNbIP) {// no SD vertices founded
00336       aVF=aV;
00337       aLVSD.Append(aV);
00338       aMVProcessed.Add(aV);
00339     }
00340     else { // SD vertices founded [ aMIPC ]
00341       aIt1.Initialize(aMIPC);
00342       for(j=0; aIt1.More(); aIt1.Next(), ++j) {
00343        aIP=aIt1.Key();
00344        const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
00345        if (!j) {
00346          aVF=aVP;
00347        }
00348        aLVSD.Append(aVP);
00349        aMVProcessed.Add(aVP);
00350       }
00351     }
00352     myImages.Bind(aVF, aLVSD);
00353   }// for (i=1; i<=aNbV; ++i) {
00354   //------------------------------
00355   //
00356   // Make new vertices
00357   aMV.Clear();
00358   aItIm.Initialize(myImages);
00359   for (; aItIm.More(); aItIm.Next()) {
00360     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aItIm.Key());
00361     const TopTools_ListOfShape& aLVSD=aItIm.Value();
00362     aNbVSD=aLVSD.Extent();
00363     if (aNbVSD>1) {
00364       aMV.Add(aV);
00365       MakeVertex(aLVSD, aVnew);
00366       aMVV.Bind(aVnew, aLVSD);
00367     }
00368   }
00369   //
00370   // UnBind old vertices
00371   aNbV=aMV.Extent();
00372   for (i=1; i<=aNbV; ++i) {
00373     const TopoDS_Shape& aV=aMV(i);
00374     myImages.UnBind(aV);
00375   }
00376   //
00377   // Bind new vertices
00378   aItIm.Initialize(aMVV);
00379   for (; aItIm.More(); aItIm.Next()) {
00380     const TopoDS_Shape& aV=aItIm.Key();
00381     const TopTools_ListOfShape& aLVSD=aItIm.Value();
00382     myImages.Bind(aV, aLVSD);
00383   }
00384   //
00385   // Origins
00386   aItIm.Initialize(myImages);
00387   for (; aItIm.More(); aItIm.Next()) {
00388     const TopoDS_Shape& aV=aItIm.Key();
00389     const TopTools_ListOfShape& aLVSD=aItIm.Value();
00390     aItS.Initialize(aLVSD);
00391     for (; aItS.More(); aItS.Next()) {
00392       const TopoDS_Shape& aVSD=aItS.Value();
00393       if (!myOrigins.IsBound(aVSD)) {
00394        myOrigins.Bind(aVSD, aV);
00395       }
00396     }
00397   }
00398 }
00399 //=======================================================================
00400 //function : MakeSubShapes
00401 //purpose  :
00402 //=======================================================================
00403 void GEOMAlgo_Gluer::MakeSubShapes (const TopoDS_Shape&  theShape,
00404                                     TopTools_MapOfShape& theMS,
00405                                     TopoDS_Compound&     theResult)
00406 {
00407   if (theMS.Contains(theShape))
00408     return;
00409   //
00410   BRep_Builder aBB;
00411   //
00412   theMS.Add(theShape);
00413   //
00414   if (theShape.ShapeType() == TopAbs_COMPOUND ||
00415       theShape.ShapeType() == TopAbs_COMPSOLID)  {
00416     TopoDS_Iterator It (theShape, Standard_True, Standard_True);
00417     for (; It.More(); It.Next())    {
00418       MakeSubShapes(It.Value(), theMS, theResult);
00419     }
00420   }
00421   else if (theShape.ShapeType() == TopAbs_SOLID)  {
00422     // build a solid
00423     TopoDS_Solid aNewSolid;
00424     TopExp_Explorer aExpS, aExp;
00425     //
00426     const TopoDS_Solid& aSolid = TopoDS::Solid(theShape);
00427     //
00428     TopAbs_Orientation anOr = aSolid.Orientation();
00429     //
00430     aBB.MakeSolid(aNewSolid);
00431     aNewSolid.Orientation(anOr);
00432     //
00433     aExp.Init(aSolid, TopAbs_SHELL);
00434     for (; aExp.More(); aExp.Next())
00435     {
00436       const TopoDS_Shape& aShell=aExp.Current();
00437       const TopoDS_Shape& aShellR=myOrigins.Find(aShell);
00438       aBB.Add(aNewSolid, aShellR);
00439     }
00440     //
00441     TopTools_ListOfShape aLS;
00442     //
00443     aLS.Append(aSolid);
00444     myImages.Bind(aNewSolid, aLS);
00445     myOrigins.Bind(aSolid, aNewSolid);
00446     //
00447     aBB.Add(theResult, aNewSolid);
00448   }
00449   else if (theShape.ShapeType() == TopAbs_WIRE)  {
00450     if (myKeepNonSolids)    {
00451       // just add image
00452       if (!myOrigins.IsBound(theShape))   {
00453         // build wire
00454         const TopoDS_Wire& aW=TopoDS::Wire(theShape);
00455         //
00456         TopoDS_Wire newWire;
00457         aBB.MakeWire(newWire);
00458         //
00459         TopExp_Explorer aExpE (aW, TopAbs_EDGE);
00460         for (; aExpE.More(); aExpE.Next()) {
00461           const TopoDS_Edge& aE=TopoDS::Edge(aExpE.Current());
00462           TopoDS_Edge aER=TopoDS::Edge(myOrigins.Find(aE));
00463           //
00464           aER.Orientation(TopAbs_FORWARD);
00465           if (!BRep_Tool::Degenerated(aER)) {
00466             // build p-curve
00467             //if (bIsUPeriodic) {
00468             //  GEOMAlgo_Tools::RefinePCurveForEdgeOnFace(aER, aFFWD, aUMin, aUMax);
00469             //}
00470             //BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aER, aFFWD);
00471             //
00472             // orient image
00473             Standard_Boolean bIsToReverse=BOPTools_Tools3D::IsSplitToReverse1(aER, aE, myContext);
00474             if (bIsToReverse) {
00475               aER.Reverse();
00476             }
00477           }
00478           else {
00479             aER.Orientation(aE.Orientation());
00480           }
00481           //
00482           aBB.Add(newWire, aER);
00483         }
00484         // xf
00485         TopTools_ListOfShape aLW;
00486         //
00487         aLW.Append(aW);
00488         myImages.Bind(newWire, aLW);
00489         myOrigins.Bind(aW, newWire);
00490       }
00491       const TopoDS_Shape& aShapeR = myOrigins.Find(theShape);
00492       aBB.Add(theResult, aShapeR);
00493     }
00494   }
00495   else
00496   {
00497     if (myKeepNonSolids)    {
00498       // just add image
00499       const TopoDS_Shape& aShapeR = myOrigins.Find(theShape);
00500       aBB.Add(theResult, aShapeR);
00501     }
00502   }
00503 }
00504 //=======================================================================
00505 //function : MakeSolids
00506 //purpose  :
00507 //=======================================================================
00508 void GEOMAlgo_Gluer::MakeSolids()
00509 {
00510   myErrorStatus=0;
00511   //
00512   BRep_Builder aBB;
00513   TopoDS_Compound aCmp;
00514   TopTools_MapOfShape aMS;
00515   //
00516   aBB.MakeCompound(aCmp);
00517   //
00518   // Add images of all initial sub-shapes in the result.
00519   // If myKeepNonSolids==false, add only solids images.
00520   MakeSubShapes(myShape, aMS, aCmp);
00521   //
00522   myResult=aCmp;
00523   //
00524   if (aMS.Extent()) {
00525     BOP_CorrectTolerances::CorrectCurveOnSurface(myResult);
00526   }
00527 }
00528 //=======================================================================
00529 //function : MakeShells
00530 //purpose  :
00531 //=======================================================================
00532 void GEOMAlgo_Gluer::MakeShells()
00533 {
00534   myErrorStatus=0;
00535   //
00536   Standard_Boolean bIsToReverse;
00537   Standard_Integer i, aNbS;
00538   TopAbs_Orientation anOr;
00539   TopoDS_Shell aNewShell;
00540   TopoDS_Face aFR;
00541   TopTools_IndexedMapOfShape aMS;
00542   TopExp_Explorer aExp;
00543   BRep_Builder aBB;
00544   //
00545   TopExp::MapShapes(myShape, TopAbs_SHELL, aMS);
00546   //
00547   aNbS=aMS.Extent();
00548   for (i=1; i<=aNbS; ++i) {
00549     const TopoDS_Shell& aShell=TopoDS::Shell(aMS(i));
00550     anOr=aShell.Orientation();
00551     //
00552     aBB.MakeShell(aNewShell);
00553     aNewShell.Orientation(anOr);
00554     aExp.Init(aShell, TopAbs_FACE);
00555     for (; aExp.More(); aExp.Next()) {
00556       const TopoDS_Face& aF=TopoDS::Face(aExp.Current());
00557       aFR=TopoDS::Face(myOrigins.Find(aF));
00558       if (aFR.IsSame(aF)) {
00559        aBB.Add(aNewShell, aF);
00560        continue;
00561       }
00562       bIsToReverse=IsToReverse(aFR, aF);
00563       if (bIsToReverse) {
00564        aFR.Reverse();
00565       }
00566       aBB.Add(aNewShell, aFR);
00567     }
00568     //
00569     TopTools_ListOfShape aLS;
00570     //
00571     aLS.Append(aShell);
00572     myImages.Bind(aNewShell, aLS);
00573     myOrigins.Bind(aShell, aNewShell);
00574   }
00575 }
00576 //=======================================================================
00577 //function : MakeFaces
00578 //purpose  :
00579 //=======================================================================
00580 void GEOMAlgo_Gluer::MakeFaces()
00581 {
00582   MakeShapes(TopAbs_FACE);
00583 }
00584 //=======================================================================
00585 //function : MakeEdges
00586 //purpose  :
00587 //=======================================================================
00588 void GEOMAlgo_Gluer::MakeEdges()
00589 {
00590   MakeShapes(TopAbs_EDGE);
00591 }
00592 //=======================================================================
00593 //function : MakeShapes
00594 //purpose  :
00595 //=======================================================================
00596 void GEOMAlgo_Gluer::MakeShapes(const TopAbs_ShapeEnum aType)
00597 {
00598   myErrorStatus=0;
00599   //
00600   Standard_Boolean bHasNewSubShape;
00601   Standard_Integer i, aNbF, aNbSDF, iErr;
00602   TopoDS_Shape aNewShape;
00603   TopTools_IndexedMapOfShape aMF;
00604   TopTools_ListIteratorOfListOfShape aItS;
00605   GEOMAlgo_PassKeyShape aPKF;
00606   GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
00607   //
00608   TopExp::MapShapes(myShape, aType, aMF);
00609   //
00610   aNbF=aMF.Extent();
00611   for (i=1; i<=aNbF; ++i) {
00612     const TopoDS_Shape& aS=aMF(i);
00613     //
00614     if (aType==TopAbs_FACE) {
00615       const TopoDS_Face& aF=TopoDS::Face(aS);
00616       FacePassKey(aF, aPKF);
00617     }
00618     else if (aType==TopAbs_EDGE) {
00619       const TopoDS_Edge& aE=TopoDS::Edge(aS);
00620       EdgePassKey(aE, aPKF);
00621     }
00622     //
00623     if (myErrorStatus) {
00624       return;
00625     }
00626     //
00627     if (aMPKLF.Contains(aPKF)) {
00628       TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
00629       aLSDF.Append(aS);
00630     }
00631     else {
00632       TopTools_ListOfShape aLSDF;
00633       //
00634       aLSDF.Append(aS);
00635       aMPKLF.Add(aPKF, aLSDF);
00636     }
00637   }
00638   // check geometric coincidence
00639   if (myCheckGeometry) {
00640     iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTol, myContext);
00641     if (iErr) {
00642       myErrorStatus=200;
00643       return;
00644     }
00645   }
00646   //
00647   // Images/Origins
00648   //
00649   aNbF=aMPKLF.Extent();
00650   for (i=1; i<=aNbF; ++i) {
00651     const TopTools_ListOfShape& aLSDF=aMPKLF(i);
00652     aNbSDF=aLSDF.Extent();
00653     if (!aNbSDF) {
00654       myErrorStatus=4; // it must not be
00655     }
00656     //
00657     const TopoDS_Shape& aS1=aLSDF.First();
00658     //
00659     bHasNewSubShape=Standard_True;
00660     // prevent creation of a new shape if there are not
00661     // new sub-shapes of aSS among the originals
00662     if (aNbSDF==1) {
00663       bHasNewSubShape=HasNewSubShape(aS1);
00664       if (!bHasNewSubShape) {
00665        aNewShape=aS1;
00666        aNewShape.Orientation(TopAbs_FORWARD);
00667       }
00668     }
00669     //
00670     if (bHasNewSubShape) {
00671       if (aType==TopAbs_FACE) {
00672        TopoDS_Face aNewFace;
00673        //
00674        const TopoDS_Face& aF1=TopoDS::Face(aS1);
00675        MakeFace(aF1, aNewFace);
00676        aNewShape=aNewFace;
00677       }
00678       else if (aType==TopAbs_EDGE) {
00679        TopoDS_Edge aNewEdge;
00680        //
00681        const TopoDS_Edge& aE1=TopoDS::Edge(aS1);
00682        MakeEdge(aE1, aNewEdge);
00683        aNewShape=aNewEdge;
00684       }
00685     }
00686     //
00687     myImages.Bind(aNewShape, aLSDF);
00688     // origins
00689     aItS.Initialize(aLSDF);
00690     for (; aItS.More(); aItS.Next()) {
00691       const TopoDS_Shape& aFSD=aItS.Value();
00692       if (!myOrigins.IsBound(aFSD)) {
00693        myOrigins.Bind(aFSD, aNewShape);
00694       }
00695     }
00696   }
00697 }
00698 //=======================================================================
00699 //function : CheckResult
00700 //purpose  :
00701 //=======================================================================
00702 void GEOMAlgo_Gluer::CheckResult()
00703 {
00704   myErrorStatus=0;
00705   //
00706   if (myResult.IsNull()) {
00707     myErrorStatus=6;
00708     return;
00709   }
00710   //
00711   Standard_Boolean bFound;
00712   Standard_Integer i, j, aNbS, aNbFS, aNbSx;
00713   TopTools_IndexedMapOfShape aMS, aMFS;
00714   TopTools_IndexedDataMapOfShapeListOfShape aMFR;
00715   //
00716   TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, TopAbs_SOLID, aMFR);
00717   TopExp::MapShapes(myResult, TopAbs_SOLID, aMS);
00718   //
00719 
00720   myNbAlone=0;
00721   aNbS=aMS.Extent();
00722   for (i=1; i<=aNbS; ++i) {
00723     const TopoDS_Shape& aSolid=aMS(i);
00724     //
00725     aMFS.Clear();
00726     TopExp::MapShapes(aSolid, TopAbs_FACE, aMFS);
00727     //
00728     bFound=Standard_False;
00729     aNbFS=aMFS.Extent();
00730     for (j=1; j<=aNbFS; ++j) {
00731       const TopoDS_Shape& aFS=aMFS(j);
00732       if (aMFR.Contains(aFS)) {
00733        const TopTools_ListOfShape& aLSx=aMFR.FindFromKey(aFS);
00734        aNbSx=aLSx.Extent();
00735        if (aNbSx==2) {
00736          bFound=!bFound;
00737          break;
00738        }
00739       }
00740     }
00741     //
00742     if (!bFound) {
00743       myWarningStatus=1;
00744       ++myNbAlone;
00745       //break;
00746     }
00747   }
00748 }
00749 //=======================================================================
00750 //function : CheckData
00751 //purpose  :
00752 //=======================================================================
00753 void GEOMAlgo_Gluer::CheckData()
00754 {
00755   myErrorStatus=0;
00756   //
00757   if (myShape.IsNull()) {
00758     myErrorStatus=5;
00759     return;
00760   }
00761 }
00762 //=======================================================================
00763 //function : InnerTolerance
00764 //purpose  :
00765 //=======================================================================
00766 void GEOMAlgo_Gluer::InnerTolerance()
00767 {
00768   myErrorStatus=0;
00769   //
00770   /*
00771   Standard_Integer i;
00772   Standard_Real aX[3][2], dH, dHmin, aCoef, aTolTresh;
00773   Bnd_Box aBox;
00774   //
00775   BRepBndLib::Add(myShape, aBox);
00776   aBox.Get(aX[0][0], aX[1][0], aX[2][0], aX[0][1], aX[1][1], aX[2][1]);
00777   //
00778   dHmin=aX[0][1]-aX[0][0];
00779   for (i=1; i<3; ++i) {
00780     dH=aX[i][1]-aX[i][0];
00781     if (dH<dHmin) {
00782       dHmin=dH;
00783     }
00784   }
00785   //
00786   myTol=myTolerance;
00787   aCoef=0.01;
00788   aTolTresh=aCoef*dHmin;
00789   if (myTol>aTolTresh) {
00790     myTol=aTolTresh;
00791   }
00792   */
00793   myTol=myTolerance;
00794 }
00795 //=======================================================================
00796 //function : FacePassKey
00797 //purpose  :
00798 //=======================================================================
00799 void GEOMAlgo_Gluer::FacePassKey(const TopoDS_Face& aF,
00800                              GEOMAlgo_PassKeyShape& aPK)
00801 {
00802   Standard_Integer i, aNbE;
00803   TopTools_ListOfShape aLE;
00804   TopTools_IndexedMapOfShape aME;
00805   //
00806   TopExp::MapShapes(aF, TopAbs_EDGE, aME);
00807   aNbE=aME.Extent();
00808   //
00809   for (i=1; i<=aNbE; ++i) {
00810     const TopoDS_Shape& aE=aME(i);
00811     if (!myOrigins.IsBound(aE)) {
00812       myErrorStatus=102;
00813       return;
00814     }
00815     const TopoDS_Shape& aER=myOrigins.Find(aE);
00816     aLE.Append(aER);
00817   }
00818   aPK.SetShapes(aLE);
00819 }
00820 //=======================================================================
00821 //function : EdgePassKey
00822 //purpose  :
00823 //=======================================================================
00824 void GEOMAlgo_Gluer::EdgePassKey(const TopoDS_Edge& aE,
00825                              GEOMAlgo_PassKeyShape& aPK)
00826 {
00827   TopoDS_Vertex aV1, aV2;
00828   //
00829   TopExp::Vertices(aE, aV1, aV2);
00830   //
00831   if (!myOrigins.IsBound(aV1) || !myOrigins.IsBound(aV2) ) {
00832      myErrorStatus=100;
00833      return;
00834   }
00835   const TopoDS_Shape& aVR1=myOrigins.Find(aV1);
00836   const TopoDS_Shape& aVR2=myOrigins.Find(aV2);
00837   aPK.SetShapes(aVR1, aVR2);
00838 }
00839 //=======================================================================
00840 //function : MakeVertex
00841 //purpose  :
00842 //=======================================================================
00843 void GEOMAlgo_Gluer::MakeVertex(const TopTools_ListOfShape& aLV,
00844                             TopoDS_Vertex& aNewVertex)
00845 {
00846   Standard_Integer aNbV;
00847   Standard_Real aTolV, aD, aDmax;
00848   gp_XYZ aGC;
00849   gp_Pnt aP3D, aPGC;
00850   TopoDS_Vertex aVx;
00851   BRep_Builder aBB;
00852   TopTools_ListIteratorOfListOfShape aIt;
00853   //
00854   aNbV=aLV.Extent();
00855   if (!aNbV) {
00856     return;
00857   }
00858   //
00859   // center of gravity
00860   aGC.SetCoord(0.,0.,0.);
00861   aIt.Initialize(aLV);
00862   for (; aIt.More(); aIt.Next()) {
00863     aVx=TopoDS::Vertex(aIt.Value());
00864     aP3D=BRep_Tool::Pnt(aVx);
00865     aGC+=aP3D.XYZ();
00866   }
00867   aGC/=(Standard_Real)aNbV;
00868   aPGC.SetXYZ(aGC);
00869   //
00870   // tolerance value
00871   aDmax=-1.;
00872   aIt.Initialize(aLV);
00873   for (; aIt.More(); aIt.Next()) {
00874     aVx=TopoDS::Vertex(aIt.Value());
00875     aP3D=BRep_Tool::Pnt(aVx);
00876     aTolV=BRep_Tool::Tolerance(aVx);
00877     aD=aPGC.Distance(aP3D)+aTolV;
00878     if (aD>aDmax) {
00879       aDmax=aD;
00880     }
00881   }
00882   //
00883   aBB.MakeVertex (aNewVertex, aPGC, aDmax);
00884 }
00885 //=======================================================================
00886 //function : MakeEdge
00887 //purpose  :
00888 //=======================================================================
00889 void GEOMAlgo_Gluer::MakeEdge(const TopoDS_Edge& aE,
00890                            TopoDS_Edge& aNewEdge)
00891 {
00892   myErrorStatus=0;
00893   //
00894   Standard_Boolean bIsDE;
00895   Standard_Real aT1, aT2;
00896   TopoDS_Vertex aV1, aV2, aVR1, aVR2;
00897   TopoDS_Edge aEx;
00898   //
00899   bIsDE=BRep_Tool::Degenerated(aE);
00900   //
00901   aEx=aE;
00902   aEx.Orientation(TopAbs_FORWARD);
00903   //
00904   TopExp::Vertices(aEx, aV1, aV2);
00905   //
00906   aT1=BRep_Tool::Parameter(aV1, aEx);
00907   aT2=BRep_Tool::Parameter(aV2, aEx);
00908   //
00909   aVR1=TopoDS::Vertex(myOrigins.Find(aV1));
00910   aVR1.Orientation(TopAbs_FORWARD);
00911   aVR2=TopoDS::Vertex(myOrigins.Find(aV2));
00912   aVR2.Orientation(TopAbs_REVERSED);
00913   //
00914   if (bIsDE) {
00915     Standard_Real aTol;
00916     BRep_Builder aBB;
00917     TopoDS_Edge E;
00918     TopAbs_Orientation anOrE;
00919     //
00920     anOrE=aE.Orientation();
00921     aTol=BRep_Tool::Tolerance(aE);
00922     //
00923     E=aEx;
00924     E.EmptyCopy();
00925     //
00926     aBB.Add  (E, aVR1);
00927     aBB.Add  (E, aVR2);
00928     aBB.Range(E, aT1, aT2);
00929     aBB.Degenerated(E, Standard_True);
00930     aBB.UpdateEdge(E, aTol);
00931     //
00932     aNewEdge=E;
00933   }
00934   //
00935   else {
00936     BOPTools_Tools::MakeSplitEdge(aEx, aVR1, aT1, aVR2, aT2, aNewEdge);
00937   }
00938 }
00939 //=======================================================================
00940 //function : MakeFace
00941 //purpose  :
00942 //=======================================================================
00943 void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF,
00944                            TopoDS_Face& aNewFace)
00945 {
00946   myErrorStatus=0;
00947   //
00948   Standard_Boolean bIsToReverse, bIsUPeriodic;
00949   Standard_Real aTol, aUMin, aUMax, aVMin, aVMax;
00950   TopoDS_Edge aER;
00951   TopoDS_Wire newWire;
00952   TopoDS_Face aFFWD, newFace;
00953   TopLoc_Location aLoc;
00954   Handle(Geom_Surface) aS;
00955   Handle(Geom2d_Curve) aC2D;
00956   TopExp_Explorer aExpW, aExpE;
00957   BRep_Builder aBB;
00958   //
00959   aFFWD=aF;
00960   aFFWD.Orientation(TopAbs_FORWARD);
00961   //
00962   aS=BRep_Tool::Surface(aFFWD, aLoc);
00963   bIsUPeriodic=GEOMAlgo_Tools::IsUPeriodic(aS);
00964   aTol=BRep_Tool::Tolerance(aFFWD);
00965   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
00966   //
00967   aBB.MakeFace (newFace, aS, aLoc, aTol);
00968   //
00969   aExpW.Init(aFFWD, TopAbs_WIRE);
00970   for (; aExpW.More(); aExpW.Next()) {
00971     aBB.MakeWire(newWire);
00972     const TopoDS_Wire& aW=TopoDS::Wire(aExpW.Current());
00973     aExpE.Init(aW, TopAbs_EDGE);
00974     for (; aExpE.More(); aExpE.Next()) {
00975       const TopoDS_Edge& aE=TopoDS::Edge(aExpE.Current());
00976       aER=TopoDS::Edge(myOrigins.Find(aE));
00977       //
00978       aER.Orientation(TopAbs_FORWARD);
00979       if (!BRep_Tool::Degenerated(aER)) {
00980        // build p-curve
00981        if (bIsUPeriodic) {
00982          GEOMAlgo_Tools::RefinePCurveForEdgeOnFace(aER, aFFWD, aUMin, aUMax);
00983        }
00984        BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aER, aFFWD);
00985 
00986        // orient image
00987        bIsToReverse=BOPTools_Tools3D::IsSplitToReverse1(aER, aE, myContext);
00988        if (bIsToReverse) {
00989          aER.Reverse();
00990        }
00991       }
00992       else {
00993        aER.Orientation(aE.Orientation());
00994       }
00995       //
00996       aBB.Add(newWire, aER);
00997     }
00998     // xf
00999     TopTools_ListOfShape aLW;
01000     //
01001     aLW.Append(aW);
01002     myImages.Bind(newWire, aLW);
01003     myOrigins.Bind(aW, newWire);
01004     // xt
01005     aBB.Add(newFace, newWire);
01006   }
01007   aNewFace=newFace;
01008 }
01009 //=======================================================================
01010 //function : IsToReverse
01011 //purpose  :
01012 //=======================================================================
01013 Standard_Boolean GEOMAlgo_Gluer::IsToReverse(const TopoDS_Face& aFR,
01014                                         const TopoDS_Face& aF)
01015 {
01016   Standard_Boolean bRet;
01017   Standard_Real aT, aT1, aT2, aTR, aScPr;
01018   TopExp_Explorer aExp;
01019   Handle(Geom_Curve)aC3D;
01020   gp_Pnt aP;
01021   gp_Dir aDNF, aDNFR;
01022   //
01023   bRet=Standard_False;
01024   //
01025   aExp.Init(aF, TopAbs_EDGE);
01026   for (; aExp.More(); aExp.Next()) {
01027     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
01028     //
01029     if (BRep_Tool::Degenerated(aE)) {
01030       continue;
01031     }
01032     //
01033     const TopoDS_Edge& aER=TopoDS::Edge(myOrigins.Find(aE));
01034     //
01035     aC3D=BRep_Tool::Curve(aE, aT1, aT2);
01036     aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
01037     aC3D->D0(aT, aP);
01038     myContext->ProjectPointOnEdge(aP, aER, aTR);
01039     //
01040     BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
01041     if (aF.Orientation()==TopAbs_REVERSED) {
01042       aDNF.Reverse();
01043     }
01044     //
01045     BOPTools_Tools3D::GetNormalToFaceOnEdge (aER, aFR, aTR, aDNFR);
01046     if (aFR.Orientation()==TopAbs_REVERSED) {
01047       aDNFR.Reverse();
01048     }
01049     //
01050     aScPr=aDNF*aDNFR;
01051     return (aScPr<0.);
01052   }
01053   return bRet;
01054 }
01055 //=======================================================================
01056 //function : HasNewSubShape
01057 //purpose  :
01058 //=======================================================================
01059 Standard_Boolean GEOMAlgo_Gluer::HasNewSubShape(const TopoDS_Shape& aS)const
01060 {
01061   Standard_Boolean bRet;
01062   Standard_Integer i, aNbSS;
01063   TopTools_IndexedMapOfShape aMSS;
01064   //
01065   GetSubShapes(aS, aMSS);
01066   //
01067   bRet=Standard_False;
01068   aNbSS=aMSS.Extent();
01069   for (i=1; i<=aNbSS; ++i) {
01070     const TopoDS_Shape& aSS=aMSS(i);
01071     if (aSS.ShapeType()==TopAbs_WIRE) {
01072       continue;
01073     }
01074     //
01075     bRet=!myOrigins.IsBound(aSS);
01076     if (bRet) {
01077       return bRet;
01078     }
01079     //
01080     const TopoDS_Shape& aSSIm=myOrigins.Find(aSS);
01081     bRet=!aSSIm.IsSame(aSS);
01082     if (bRet) {
01083       return bRet;
01084     }
01085   }
01086   return bRet;
01087 }
01088 //=======================================================================
01089 //function : GetSubShapes
01090 //purpose  :
01091 //=======================================================================
01092 void GetSubShapes(const TopoDS_Shape& aS,
01093                 TopTools_IndexedMapOfShape& aMSS)
01094 {
01095   Standard_Integer aR;
01096   TopAbs_ShapeEnum aType;
01097   TopoDS_Iterator aIt;
01098   //
01099   aType=aS.ShapeType();
01100   aR=(Standard_Integer)aType+1;
01101   if (aR>TopAbs_VERTEX) {
01102     return;
01103   }
01104   //
01105   aIt.Initialize(aS);
01106   for (; aIt.More(); aIt.Next()) {
01107     const TopoDS_Shape& aSS=aIt.Value();
01108     aMSS.Add(aSS);
01109     GetSubShapes(aSS, aMSS);
01110   }
01111 }
01112 //=======================================================================
01113 //function : Modified
01114 //purpose  :
01115 //=======================================================================
01116 const TopTools_ListOfShape& GEOMAlgo_Gluer::Modified (const TopoDS_Shape& aS)
01117 {
01118   TopAbs_ShapeEnum aType;
01119   //
01120   myGenerated.Clear();
01121   //
01122   aType=aS.ShapeType();
01123   if (aType==TopAbs_VERTEX ||
01124       aType==TopAbs_EDGE   ||
01125       aType==TopAbs_WIRE   ||
01126       aType==TopAbs_FACE   ||
01127       aType==TopAbs_SHELL  ||
01128       aType==TopAbs_SOLID) {
01129     if(myOrigins.IsBound(aS)) {
01130       const TopoDS_Shape& aSnew=myOrigins.Find(aS);
01131       if (!aSnew.IsSame(aS)) {
01132        myGenerated.Append(aSnew);
01133       }
01134     }
01135   }
01136   //
01137   return myGenerated;
01138 }
01139 //=======================================================================
01140 //function : Generated
01141 //purpose  :
01142 //=======================================================================
01143 const TopTools_ListOfShape& GEOMAlgo_Gluer::Generated(const TopoDS_Shape& )
01144 {
01145   myGenerated.Clear();
01146   return myGenerated;
01147 }
01148 //=======================================================================
01149 //function : IsDeleted
01150 //purpose  :
01151 //=======================================================================
01152 Standard_Boolean GEOMAlgo_Gluer::IsDeleted (const TopoDS_Shape& aS)
01153 {
01154   Standard_Boolean bRet=Standard_False;
01155   //
01156   const TopTools_ListOfShape& aL=Modified(aS);
01157   bRet=!aL.IsEmpty();
01158   //
01159   return bRet;
01160 }
01161 
01162 //
01163 // ErrorStatus
01164 //
01165 // 1   - the object is just initialized
01166 // 2   - no vertices found in source shape
01167 // 3   - nb same domain vertices for the vertex Vi =0
01168 // 4   - nb same domain edges(faces) for the edge Ei(face Fi)  =0
01169 // 5   - source shape is Null
01170 // 6   - result shape is Null
01171 // 101 - nb edges > PassKey.NbMax() in FacesPassKey()
01172 // 102 - the edge Ei can not be found in myOrigins Map
01173 // 100 - the vertex Vi can not be found in myOrigins Map
01174 //
01175 // WarningStatus
01176 //
01177 // 1   - some shapes can not be glued by faces
01178 //