Back to index

salome-geom  6.5.0
ShHealOper_Sewing.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:      ShHealOper_Sewing.cxx
00024 // Created:   29.04.04 15:07:10
00025 // Author:    Galina KULIKOVA
00026 //
00027 #include <ShHealOper_Sewing.hxx>
00028 #include <TopExp_Explorer.hxx>
00029 #include <TopoDS_Shell.hxx>
00030 #include <BRep_Builder.hxx>
00031 #include <ShapeFix_Shell.hxx>
00032 #include <TopTools_HSequenceOfShape.hxx>
00033 #include <TopoDS_Shell.hxx>
00034 #include <BRep_Builder.hxx>
00035 #include <ShapeAnalysis_FreeBounds.hxx>
00036 #include <TopoDS_Compound.hxx>
00037 #include <TopoDS.hxx>
00038 #include <TopoDS_Iterator.hxx>
00039 #include <TopTools_MapOfShape.hxx>
00040 //=======================================================================
00041 //function : ShHealOper_Sewing()
00042 //purpose  : Constructor
00043 //=======================================================================
00044 
00045 
00046 ShHealOper_Sewing::ShHealOper_Sewing (const TopoDS_Shape& theShape,
00047                                      const Standard_Real theTolerance)
00048 {
00049   Init(theShape);
00050   myTolerance = theTolerance;
00051 }
00052 //=======================================================================
00053 //function : Init
00054 //purpose  : 
00055 //=======================================================================
00056 
00057 void ShHealOper_Sewing::Init(const TopoDS_Shape& theShape)
00058 {
00059   ShHealOper_Tool::Init(theShape);
00060   myTolerance = Precision::Confusion();
00061   myEdgesMode = Standard_False;
00062   myFacesMode = Standard_True;
00063   myNonManifoldMode = Standard_False;
00064   myHistoryLevel = TopAbs_FACE;
00065 }
00066 //=======================================================================
00067 //function : Perform
00068 //purpose  : 
00069 //=======================================================================
00070 
00071 Standard_Boolean ShHealOper_Sewing::Perform()
00072 {
00073   TopTools_SequenceOfShape theSeqShapes;
00074   return sewing(theSeqShapes);
00075 }
00076 //=======================================================================
00077 //function : Perform
00078 //purpose  : 
00079 //=======================================================================
00080 
00081 Standard_Boolean ShHealOper_Sewing::Perform(const TopTools_SequenceOfShape& theSeqShapes)
00082 {
00083   return sewing(theSeqShapes);
00084 }
00085 
00086 //=======================================================================
00087 //function : sewing
00088 //purpose  : 
00089 //=======================================================================
00090 
00091 Standard_Boolean ShHealOper_Sewing::sewing(const TopTools_SequenceOfShape& theSeqShapes)
00092 {
00093   myDone = Standard_False;
00094   myErrorStatus = ShHealOper_NotError;
00095   if(myInitShape.IsNull()) {
00096     myErrorStatus = ShHealOper_InvalidParameters;
00097     return myDone;
00098   }
00099   //sewing shape
00100   Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
00101   aSewing->Load(myInitShape);
00102   aSewing->SetTolerance(myTolerance);
00103   aSewing->SetFaceMode(myFacesMode);
00104   aSewing->SetFloatingEdgesMode(myEdgesMode);
00105   aSewing->SetNonManifoldMode(myNonManifoldMode);
00106   Standard_Integer j =1;
00107   for( ; j <= theSeqShapes.Length();j++)
00108     aSewing->Add(theSeqShapes.Value(j));
00109 
00110   aSewing->Perform();
00111   const TopoDS_Shape aSewShape = aSewing->SewedShape();
00112   if(aSewShape.IsNull()) {
00113     myErrorStatus = ShHealOper_ErrorExecution;
00114     return myDone;
00115   }
00116   if(aSewShape.IsSame(myInitShape))
00117     return myDone;
00118 
00119   //analysis either sewing was made by changing number of shells
00120   myDone = isSewed(aSewShape);
00121 
00122   //keep modification of the sub-shapes in the Context.
00123   TopExp_Explorer aExp(myInitShape,TopAbs_FACE);
00124   for( ; aExp.More(); aExp.Next())
00125     myDone = (getModifications( aExp.Current(),aSewing) || myDone);
00126 
00127   TopoDS_Shape aTempShape = myContext->Apply(aSewShape);
00128   //obtained shells with fixed orientation for manifold and nonmanifold shells
00129   if(myFacesMode) 
00130     myDone = getShells(aTempShape) || myDone;
00131 
00132   //obtained manifold wires if sewing edges was performed.
00133   if(myEdgesMode) 
00134     myDone = getWires(aTempShape) || myDone;
00135   
00136   if(myDone)
00137     myResultShape = myContext->Apply(aTempShape);
00138     
00139   return myDone;
00140 }
00141 //=======================================================================
00142 //function : getShells
00143 //purpose  : 
00144 //=======================================================================
00145 
00146 Standard_Boolean ShHealOper_Sewing::getShells(const TopoDS_Shape& theSewShape) const
00147 {
00148   Standard_Boolean isDone = Standard_False;
00149   TopoDS_Shape aTmpShape = theSewShape;
00150   if(myNonManifoldMode) {
00151     TopoDS_Shell tempShell;
00152     BRep_Builder aB;
00153     aB.MakeShell(tempShell);
00154     
00155     for(TopExp_Explorer aExpf(theSewShape,TopAbs_FACE);aExpf.More(); aExpf.Next()) 
00156       aB.Add(tempShell,aExpf.Current());
00157     aTmpShape = tempShell;
00158     myContext->Replace(theSewShape,aTmpShape);
00159   }
00160   
00161   Handle(ShapeFix_Shell) asfs = new ShapeFix_Shell;
00162   asfs->SetContext(myContext);
00163   TopExp_Explorer aexpShell(aTmpShape,TopAbs_SHELL);
00164   for ( ; aexpShell.More(); aexpShell.Next()) 
00165     isDone = (asfs->FixFaceOrientation(TopoDS::Shell(aexpShell.Current()),
00166                                        Standard_True,myNonManifoldMode) || isDone);
00167   
00168   return isDone;
00169 }
00170 //=======================================================================
00171 //function : getWires
00172 //purpose  : 
00173 //=======================================================================
00174 
00175 Standard_Boolean ShHealOper_Sewing::getWires(const TopoDS_Shape& theSewShape) const
00176 {
00177   if(theSewShape.ShapeType() != TopAbs_COMPOUND)
00178     return Standard_False;
00179   
00180   Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
00181   TopExp_Explorer aexpEdges(theSewShape,TopAbs_EDGE,TopAbs_WIRE);
00182   for ( ; aexpEdges.More(); aexpEdges.Next()) {
00183     aSeqEdges->Append(aexpEdges.Current());
00184   }
00185   if(aSeqEdges->Length() <2)
00186     return Standard_False;
00187   //get manifold wires from sewed edges.
00188   Standard_Real aTol = 0.;
00189   Standard_Boolean aShared = Standard_True;
00190   Handle(TopTools_HSequenceOfShape) aTmpWires = new TopTools_HSequenceOfShape;
00191   ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, aTol, aShared, aTmpWires);
00192 
00193   TopTools_MapOfShape aMapEdges;
00194   Standard_Integer i =1;
00195   for( ; i <= aSeqEdges->Length(); i++)
00196     aMapEdges.Add(aSeqEdges->Value(i));
00197   
00198   //remove free edges from result shape.
00199   TopoDS_Compound aNewComp;
00200   deleteFreeEdges(theSewShape,aMapEdges,aNewComp);
00201   
00202   //add new wires in the result shape.
00203   BRep_Builder aB;
00204   for( i =1; i <= aTmpWires->Length(); i++) {
00205     TopoDS_Iterator aite(aTmpWires->Value(i));
00206     Standard_Integer nbe =0;
00207     TopoDS_Shape aE;
00208     for( ; aite.More() && nbe < 3; aite.Next(),nbe++)
00209       aE = aite.Value();
00210     if(!nbe)
00211       continue;
00212     else if(nbe ==1)
00213       aB.Add(aNewComp,aE);
00214     else
00215       aB.Add(aNewComp,aTmpWires->Value(i));
00216   }
00217   
00218   myContext->Replace(theSewShape,aNewComp);
00219   return Standard_True;
00220 }
00221 //=======================================================================
00222 //function : getHistory
00223 //purpose  : 
00224 //=======================================================================
00225 
00226 Standard_Boolean ShHealOper_Sewing::getModifications(const TopoDS_Shape& theShape,
00227                                                      const Handle(BRepBuilderAPI_Sewing)& theSewing) const
00228 {
00229   if((Standard_Integer)theShape.ShapeType() > (Standard_Integer)myHistoryLevel)
00230     return Standard_False;
00231   
00232   Standard_Boolean isDone = theSewing->IsModifiedSubShape(theShape);
00233   if(isDone) {
00234     TopoDS_Shape aNewShape = theSewing->ModifiedSubShape(theShape);
00235     myContext->Replace(theShape,aNewShape);
00236   }
00237   TopoDS_Iterator aIt(theShape);
00238   for( ; aIt.More(); aIt.Next()) {
00239     isDone = (getModifications( aIt.Value(),theSewing) || isDone);
00240   }
00241   return isDone;
00242     
00243 }
00244 //=======================================================================
00245 //function : isSewed
00246 //purpose  : 
00247 //=======================================================================
00248 
00249 Standard_Boolean ShHealOper_Sewing::isSewed(const TopoDS_Shape& theShape) const
00250 {
00251   Standard_Integer nbNewShells =0;
00252   Standard_Integer nbOldShells =0;
00253   TopExp_Explorer aExpShells(theShape,TopAbs_SHELL);
00254   for( ; aExpShells.More(); aExpShells.Next())
00255     nbNewShells++;
00256   for( aExpShells.Init(myInitShape,TopAbs_SHELL); aExpShells.More(); aExpShells.Next())
00257     nbOldShells++;
00258   return (nbNewShells != nbOldShells);
00259 }
00260 //=======================================================================
00261 //function : deleteFreeEdges
00262 //purpose  : 
00263 //=======================================================================
00264 
00265 void ShHealOper_Sewing::deleteFreeEdges(const TopoDS_Shape& theSewShape, 
00266                                         TopTools_MapOfShape& theMapEdges,
00267                                         TopoDS_Compound& theNewComp) const
00268 {
00269  
00270   BRep_Builder aB;
00271   aB.MakeCompound(theNewComp);
00272   TopoDS_Iterator aIt(theSewShape);
00273   
00274   for( ; aIt.More(); aIt.Next()) {
00275     if((aIt.Value().ShapeType() == TopAbs_EDGE ) && theMapEdges.Contains(aIt.Value()))
00276       continue;
00277     else if(aIt.Value().ShapeType() == TopAbs_COMPOUND) {
00278       TopoDS_Compound aC;
00279       deleteFreeEdges(aIt.Value(),theMapEdges,aC);
00280       aB.Add(theNewComp,aC);
00281     }
00282     else
00283       aB.Add(theNewComp,aIt.Value());
00284   }
00285 }