Back to index

salome-geom  6.5.0
GEOMImpl_Fillet2dDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include <Standard_Stream.hxx>
00021 
00022 #include <GEOMImpl_Fillet2dDriver.hxx>
00023 #include <GEOMImpl_IFillet2d.hxx>
00024 #include <GEOMImpl_Types.hxx>
00025 #include <GEOMImpl_ILocalOperations.hxx>
00026 #include <GEOMImpl_Block6Explorer.hxx>
00027 #include <GEOM_Function.hxx>
00028 
00029 #include <BRepFilletAPI_MakeFillet2d.hxx>
00030 #include <BRepCheck_Analyzer.hxx>
00031 #include <BRep_Tool.hxx>
00032 #include <BRep_Builder.hxx>
00033 
00034 #include <TopoDS.hxx>
00035 #include <TopoDS_Shape.hxx>
00036 #include <TopoDS_Edge.hxx>
00037 #include <TopoDS_Iterator.hxx>
00038 #include <TopAbs.hxx>
00039 #include <TopExp_Explorer.hxx>
00040 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00041 #include <TopTools_ListIteratorOfListOfShape.hxx>
00042 
00043 #include <ShapeFix_ShapeTolerance.hxx>
00044 #include <ShapeFix_Shape.hxx>
00045 
00046 #include <Precision.hxx>
00047 #include <gp_Pnt.hxx>
00048 #include <StdFail_NotDone.hxx>
00049 
00050 //=======================================================================
00051 //function : GetID
00052 //purpose  :
00053 //=======================================================================
00054 const Standard_GUID& GEOMImpl_Fillet2dDriver::GetID()
00055 {
00056   static Standard_GUID aFillet2dDriver("FF1AAB41-2A14-4df2-581B-3A568163BA46");
00057   return aFillet2dDriver;
00058 }
00059 
00060 
00061 //=======================================================================
00062 //function : GEOMImpl_Fillet2dDriver
00063 //purpose  :
00064 //=======================================================================
00065 GEOMImpl_Fillet2dDriver::GEOMImpl_Fillet2dDriver()
00066 {
00067 }
00068 
00069 //=======================================================================
00070 //function : Execute
00071 //purpose  :
00072 //=======================================================================
00073 Standard_Integer GEOMImpl_Fillet2dDriver::Execute(TFunction_Logbook& log) const
00074 {
00075   if (Label().IsNull()) return 0;
00076   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
00077 
00078   GEOMImpl_IFillet2d aCI (aFunction);
00079 
00080   TopoDS_Shape aShape;
00081 
00082   Handle(GEOM_Function) aRefShape = aCI.GetShape();
00083   TopoDS_Shape aFaceShape = aRefShape->GetValue();
00084 
00085   int aLen = aCI.GetLength();
00086   double rad = aCI.GetR();
00087 
00088   if (aFaceShape.ShapeType() == TopAbs_FACE) {
00089     BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(aFaceShape));
00090 
00091     int ind = 1;
00092     for (; ind <= aLen; ind++) {
00093       TopoDS_Shape aShapeVertex;
00094       if (GEOMImpl_ILocalOperations::GetSubShape
00095           (aFaceShape, aCI.GetVertex(ind), aShapeVertex)) {
00096         fillet2d.AddFillet(TopoDS::Vertex(aShapeVertex), rad);
00097       }
00098     }
00099 
00100     fillet2d.Build();
00101     if (!fillet2d.IsDone()) {
00102       StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
00103     }
00104     aShape = fillet2d.Shape();
00105   }
00106   else if (aFaceShape.ShapeType() == TopAbs_SHELL) {
00107     // 1. Map vertices to faces to build fillets only on corner vertices
00108     TopTools_IndexedDataMapOfShapeListOfShape mapVertexFaces;
00109     GEOMImpl_Block6Explorer::MapShapesAndAncestors
00110       (aFaceShape, TopAbs_VERTEX, TopAbs_FACE, mapVertexFaces);
00111 
00112     // 2. Map faces to vertices
00113     TopTools_IndexedDataMapOfShapeListOfShape mapFaceVertices;
00114     TopTools_ListOfShape empty;
00115     int ind = 1;
00116     for (; ind <= aLen; ind++) {
00117       TopoDS_Shape aVi;
00118       if (GEOMImpl_ILocalOperations::GetSubShape(aFaceShape, aCI.GetVertex(ind), aVi)) {
00119         Standard_Integer aVi_index = mapVertexFaces.FindIndex(aVi);
00120         if (aVi_index > 0) {
00121           const TopTools_ListOfShape& aFacesOfVi = mapVertexFaces(aVi_index);
00122           if (aFacesOfVi.Extent() == 1) { // we use only corner vertices of shell
00123             TopoDS_Shape aFi = aFacesOfVi.First();
00124             Standard_Integer aFi_index = mapFaceVertices.FindIndex(aFi);
00125             if (aFi_index == 0) aFi_index = mapFaceVertices.Add(aFi, empty);
00126             mapFaceVertices(aFi_index).Append(aVi);
00127           }
00128         }
00129       }
00130     }
00131 
00132     // 3. Build fillet on each given vertex
00133     TopoDS_Shell aResult;
00134     BRep_Builder B;
00135     B.MakeShell(aResult);
00136 
00137     TopoDS_Iterator It (aFaceShape, Standard_True, Standard_True);
00138     TopTools_MapOfShape mapShape;
00139     for (; It.More(); It.Next()) {
00140       if (mapShape.Add(It.Value())) {
00141         Standard_Integer aFi_index = mapFaceVertices.FindIndex(It.Value());
00142         if (aFi_index == 0) {
00143           // No fillets requested on this face, add it as is
00144           B.Add(aResult, It.Value());
00145         }
00146         else {
00147           // Build a fillet and add the changed face
00148           BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(It.Value()));
00149           const TopTools_ListOfShape& aVertsOfFi = mapFaceVertices(aFi_index);
00150           TopTools_ListIteratorOfListOfShape itV (aVertsOfFi);
00151           for (; itV.More(); itV.Next()) {
00152             fillet2d.AddFillet(TopoDS::Vertex(itV.Value()), rad);
00153           }
00154 
00155           fillet2d.Build();
00156           if (!fillet2d.IsDone()) {
00157             StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
00158           }
00159           TopoDS_Shape aFillet = fillet2d.Shape();
00160 
00161           B.Add(aResult, aFillet);
00162         }
00163       }
00164     }
00165 
00166     // 4. Build a shell
00167     // ?TODO?
00168     aShape = aResult;
00169   }
00170   else {
00171     Standard_ConstructionError::Raise("Wrong arguments: a face or a shell must be given");
00172   }
00173 
00174   if (aShape.IsNull()) return 0;
00175 
00176   aFunction->SetValue(aShape);
00177   log.SetTouched(Label());
00178 
00179   return 1;
00180 }
00181 
00182 
00183 //=======================================================================
00184 //function :  GEOMImpl_Fillet2dDriver_Type_
00185 //purpose  :
00186 //=======================================================================
00187 Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet2dDriver_Type_()
00188 {
00189   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
00190   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
00191   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
00192   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
00193   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
00194   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
00195 
00196   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
00197   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_Fillet2dDriver",
00198                                                          sizeof(GEOMImpl_Fillet2dDriver),
00199                                                          1,
00200                                                          (Standard_Address)_Ancestors,
00201                                                          (Standard_Address)NULL);
00202 
00203   return _aType;
00204 }
00205 
00206 //=======================================================================
00207 //function : DownCast
00208 //purpose  :
00209 //=======================================================================
00210 const Handle(GEOMImpl_Fillet2dDriver) Handle(GEOMImpl_Fillet2dDriver)::DownCast
00211                                    (const Handle(Standard_Transient)& AnObject)
00212 {
00213   Handle(GEOMImpl_Fillet2dDriver) _anOtherObject;
00214 
00215   if (!AnObject.IsNull()) {
00216      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_Fillet2dDriver))) {
00217        _anOtherObject = Handle(GEOMImpl_Fillet2dDriver)((Handle(GEOMImpl_Fillet2dDriver)&)AnObject);
00218      }
00219   }
00220 
00221   return _anOtherObject;
00222 }