Back to index

salome-geom  6.5.0
GEOMImpl_ChamferDriver.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 #include <Standard_Stream.hxx>
00024 
00025 #include <GEOMImpl_ChamferDriver.hxx>
00026 #include <GEOMImpl_IChamfer.hxx>
00027 #include <GEOMImpl_Types.hxx>
00028 #include <GEOMImpl_ILocalOperations.hxx>
00029 #include <GEOMImpl_Block6Explorer.hxx>
00030 
00031 #include <GEOM_Function.hxx>
00032 
00033 #include <BRepLib.hxx>
00034 #include <BRep_Tool.hxx>
00035 #include <BRepTools.hxx>
00036 #include <BRepFilletAPI_MakeChamfer.hxx>
00037 
00038 #include <ShapeFix_Shape.hxx>
00039 #include <ShapeFix_ShapeTolerance.hxx>
00040 
00041 #include <TopAbs.hxx>
00042 #include <TopoDS.hxx>
00043 #include <TopoDS_Edge.hxx>
00044 #include <TopoDS_Face.hxx>
00045 #include <TopoDS_Shape.hxx>
00046 #include <TopoDS_Iterator.hxx>
00047 #include <TopExp.hxx>
00048 #include <TopExp_Explorer.hxx>
00049 #include <TopTools_MapOfShape.hxx>
00050 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00051 
00052 #include <Precision.hxx>
00053 #include <gp_Pnt.hxx>
00054 #include <StdFail_NotDone.hxx>
00055 
00056 //=======================================================================
00057 //function : GetID
00058 //purpose  :
00059 //=======================================================================
00060 const Standard_GUID& GEOMImpl_ChamferDriver::GetID()
00061 {
00062   static Standard_GUID aChamferDriver("FF1BBB42-5D14-4df2-980B-3A668264EA16");
00063   return aChamferDriver;
00064 }
00065 
00066 
00067 //=======================================================================
00068 //function : GEOMImpl_ChamferDriver
00069 //purpose  :
00070 //=======================================================================
00071 GEOMImpl_ChamferDriver::GEOMImpl_ChamferDriver()
00072 {
00073 }
00074 
00075 //=======================================================================
00076 //function : isGoodForChamfer
00077 //purpose  :
00078 //=======================================================================
00079 static Standard_Boolean isGoodForChamfer (const TopoDS_Shape& theShape)
00080 {
00081   if (theShape.ShapeType() == TopAbs_SHELL ||
00082       theShape.ShapeType() == TopAbs_SOLID ||
00083       theShape.ShapeType() == TopAbs_COMPSOLID) {
00084     return Standard_True;
00085   }
00086 
00087   if (theShape.ShapeType() == TopAbs_COMPOUND) {
00088     TopTools_MapOfShape mapShape;
00089     TopoDS_Iterator It (theShape, Standard_False, Standard_False);
00090     for (; It.More(); It.Next()) {
00091       if (mapShape.Add(It.Value())) {
00092         if (!isGoodForChamfer(It.Value())) {
00093           return Standard_False;
00094         }
00095       }
00096     }
00097     return Standard_True;
00098   }
00099 
00100   return Standard_False;
00101 }
00102 
00103 //=======================================================================
00104 //function : Execute
00105 //purpose  :
00106 //=======================================================================
00107 Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const
00108 {
00109   if (Label().IsNull()) return 0;
00110   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
00111 
00112   GEOMImpl_IChamfer aCI (aFunction);
00113   Standard_Integer aType = aFunction->GetType();
00114 
00115   TopoDS_Shape aShape;
00116 
00117   Handle(GEOM_Function) aRefShape = aCI.GetShape();
00118   TopoDS_Shape aShapeBase = aRefShape->GetValue();
00119 
00120   // Check the shape type. It have to be shell
00121   // or solid, or compsolid, or compound of these shapes.
00122   if (!isGoodForChamfer(aShapeBase)) {
00123     StdFail_NotDone::Raise
00124       ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes");
00125   }
00126 
00127   BRepFilletAPI_MakeChamfer fill (aShapeBase);
00128 
00129   if (aType == CHAMFER_SHAPE_ALL) {
00130     // symmetric chamfer on all edges
00131     double aD = aCI.GetD();
00132     TopTools_IndexedDataMapOfShapeListOfShape M;
00133     GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
00134     for (int i = 1; i <= M.Extent(); i++) {
00135       TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
00136       TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
00137       if (!BRepTools::IsReallyClosed(E, F) &&
00138           !BRep_Tool::Degenerated(E) &&
00139           M.FindFromIndex(i).Extent() == 2)
00140         fill.Add(aD, E, F);
00141     }
00142   }
00143   else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) {
00144     // chamfer on edges, common to two faces, with D1 on the first face
00145 
00146     TopoDS_Shape aFace1, aFace2;
00147     if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) &&
00148         GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2))
00149     {
00150       TopoDS_Face F = TopoDS::Face(aFace1);
00151 
00152       // fill map of edges of the second face
00153       TopTools_MapOfShape aMap;
00154       TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE);
00155       for (; Exp2.More(); Exp2.Next()) {
00156         aMap.Add(Exp2.Current());
00157       }
00158 
00159       // find edges of the first face, common with the second face
00160       TopExp_Explorer Exp (aFace1, TopAbs_EDGE);
00161       for (; Exp.More(); Exp.Next()) {
00162         if (aMap.Contains(Exp.Current())) {
00163           TopoDS_Edge E = TopoDS::Edge(Exp.Current());
00164           if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
00165           {
00166             if ( aType == CHAMFER_SHAPE_EDGE )
00167             {
00168               double aD1 = aCI.GetD1();
00169               double aD2 = aCI.GetD2();
00170               fill.Add(aD1, aD2, E, F);
00171             }
00172             else
00173             {
00174               double aD = aCI.GetD();
00175               double anAngle = aCI.GetAngle();
00176               if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
00177                 fill.AddDA(aD, anAngle, E, F);
00178             }
00179           }
00180         }
00181       }
00182     }
00183   }
00184   else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) {
00185     // chamfer on all edges of the selected faces, with D1 on the selected face
00186     // (on first selected face, if the edge belongs to two selected faces)
00187 
00188     int aLen = aCI.GetLength();
00189     int ind = 1;
00190     TopTools_MapOfShape aMap;
00191     TopTools_IndexedDataMapOfShapeListOfShape M;
00192     GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
00193     for (; ind <= aLen; ind++)
00194     {
00195       TopoDS_Shape aShapeFace;
00196       if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace))
00197       {
00198         TopoDS_Face F = TopoDS::Face(aShapeFace);
00199         TopExp_Explorer Exp (F, TopAbs_EDGE);
00200         for (; Exp.More(); Exp.Next()) {
00201           if (!aMap.Contains(Exp.Current()))
00202           {
00203             TopoDS_Edge E = TopoDS::Edge(Exp.Current());
00204             if (!BRepTools::IsReallyClosed(E, F) &&
00205                 !BRep_Tool::Degenerated(E) &&
00206                 M.FindFromKey(E).Extent() == 2)
00207             {
00208               if (aType == CHAMFER_SHAPE_FACES)
00209               {
00210                 double aD1 = aCI.GetD1();
00211                 double aD2 = aCI.GetD2();
00212                 fill.Add(aD1, aD2, E, F);
00213               }
00214               else
00215               {
00216                 double aD = aCI.GetD();
00217                 double anAngle = aCI.GetAngle();
00218                 if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
00219                   fill.AddDA(aD, anAngle, E, F);
00220               }
00221             }
00222           }
00223         }
00224       }
00225     }
00226   }
00227   else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD)
00228   {
00229     // chamfer on selected edges with lenght param D1 & D2.
00230 
00231     int aLen = aCI.GetLength();
00232     int ind = 1;
00233     TopTools_MapOfShape aMap;
00234     TopTools_IndexedDataMapOfShapeListOfShape M;
00235     GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
00236     for (; ind <= aLen; ind++)
00237     {
00238       TopoDS_Shape aShapeEdge;
00239       if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge))
00240       {
00241         TopoDS_Edge E = TopoDS::Edge(aShapeEdge);
00242         const TopTools_ListOfShape& aFacesList = M.FindFromKey(E);
00243         TopoDS_Face F = TopoDS::Face( aFacesList.First() );
00244         if (aType == CHAMFER_SHAPE_EDGES)
00245         {
00246           double aD1 = aCI.GetD1();
00247           double aD2 = aCI.GetD2();
00248           fill.Add(aD1, aD2, E, F);
00249         }
00250         else
00251         {
00252           double aD = aCI.GetD();
00253           double anAngle = aCI.GetAngle();
00254           if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
00255             fill.AddDA(aD, anAngle, E, F);
00256         }
00257       }
00258     }
00259   }
00260   else {
00261   }
00262 
00263   fill.Build();
00264   if (!fill.IsDone()) {
00265     StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
00266   }
00267   aShape = fill.Shape();
00268 
00269   if (aShape.IsNull()) return 0;
00270 
00271   // reduce tolerances
00272   ShapeFix_ShapeTolerance aSFT;
00273   aSFT.LimitTolerance(aShape, Precision::Confusion(),
00274                       Precision::Confusion(), TopAbs_SHAPE);
00275   Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
00276   aSfs->Perform();
00277   aShape = aSfs->Shape();
00278 
00279   // fix SameParameter flag
00280   BRepLib::SameParameter(aShape, 1.E-5, Standard_True);
00281 
00282   aFunction->SetValue(aShape);
00283 
00284   log.SetTouched(Label());
00285 
00286   return 1;
00287 }
00288 
00289 
00290 //=======================================================================
00291 //function :  GEOMImpl_ChamferDriver_Type_
00292 //purpose  :
00293 //=======================================================================
00294 Standard_EXPORT Handle_Standard_Type& GEOMImpl_ChamferDriver_Type_()
00295 {
00296   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
00297   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
00298   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
00299   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
00300   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
00301   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
00302 
00303   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
00304   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_ChamferDriver",
00305                                                          sizeof(GEOMImpl_ChamferDriver),
00306                                                          1,
00307                                                          (Standard_Address)_Ancestors,
00308                                                          (Standard_Address)NULL);
00309 
00310   return _aType;
00311 }
00312 
00313 //=======================================================================
00314 //function : DownCast
00315 //purpose  :
00316 //=======================================================================
00317 const Handle(GEOMImpl_ChamferDriver) Handle(GEOMImpl_ChamferDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
00318 {
00319   Handle(GEOMImpl_ChamferDriver) _anOtherObject;
00320 
00321   if (!AnObject.IsNull()) {
00322      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_ChamferDriver))) {
00323        _anOtherObject = Handle(GEOMImpl_ChamferDriver)((Handle(GEOMImpl_ChamferDriver)&)AnObject);
00324      }
00325   }
00326 
00327   return _anOtherObject;
00328 }