-// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#include <GEOMImpl_IFillet2d.hxx>
#include <GEOMImpl_Types.hxx>
#include <GEOMImpl_ILocalOperations.hxx>
+#include <GEOMImpl_Block6Explorer.hxx>
#include <GEOM_Function.hxx>
#include <BRepFilletAPI_MakeFillet2d.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
#include <TopAbs.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Shape.hxx>
TopoDS_Shape aShape;
Handle(GEOM_Function) aRefShape = aCI.GetShape();
- TopoDS_Face aFaceShape = TopoDS::Face(aRefShape->GetValue());
-
- if (aFaceShape.ShapeType() != TopAbs_FACE)
- Standard_ConstructionError::Raise("Wrong arguments: two faces must be given");
-
- BRepFilletAPI_MakeFillet2d fillet2d (aFaceShape);
+ TopoDS_Shape aFaceShape = aRefShape->GetValue();
int aLen = aCI.GetLength();
- int ind = 1;
double rad = aCI.GetR();
- for (; ind <= aLen; ind++) {
- TopoDS_Shape aShapeVertex;
- if (GEOMImpl_ILocalOperations::GetSubShape
- (aFaceShape, aCI.GetVertex(ind), aShapeVertex)) {
- fillet2d.AddFillet(TopoDS::Vertex(aShapeVertex), rad);
+
+ if (aFaceShape.ShapeType() == TopAbs_FACE) {
+ BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(aFaceShape));
+
+ int ind = 1;
+ for (; ind <= aLen; ind++) {
+ TopoDS_Shape aShapeVertex;
+ if (GEOMImpl_ILocalOperations::GetSubShape
+ (aFaceShape, aCI.GetVertex(ind), aShapeVertex)) {
+ fillet2d.AddFillet(TopoDS::Vertex(aShapeVertex), rad);
+ }
+ }
+
+ fillet2d.Build();
+ if (!fillet2d.IsDone()) {
+ StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
}
+ aShape = fillet2d.Shape();
}
+ else if (aFaceShape.ShapeType() == TopAbs_SHELL) {
+ // 1. Map vertices to faces to build fillets only on corner vertices
+ TopTools_IndexedDataMapOfShapeListOfShape mapVertexFaces;
+ GEOMImpl_Block6Explorer::MapShapesAndAncestors
+ (aFaceShape, TopAbs_VERTEX, TopAbs_FACE, mapVertexFaces);
+
+ // 2. Map faces to vertices
+ TopTools_IndexedDataMapOfShapeListOfShape mapFaceVertices;
+ TopTools_ListOfShape empty;
+ int ind = 1;
+ for (; ind <= aLen; ind++) {
+ TopoDS_Shape aVi;
+ if (GEOMImpl_ILocalOperations::GetSubShape(aFaceShape, aCI.GetVertex(ind), aVi)) {
+ Standard_Integer aVi_index = mapVertexFaces.FindIndex(aVi);
+ if (aVi_index > 0) {
+ const TopTools_ListOfShape& aFacesOfVi = mapVertexFaces(aVi_index);
+ if (aFacesOfVi.Extent() == 1) { // we use only corner vertices of shell
+ TopoDS_Shape aFi = aFacesOfVi.First();
+ Standard_Integer aFi_index = mapFaceVertices.FindIndex(aFi);
+ if (aFi_index == 0) aFi_index = mapFaceVertices.Add(aFi, empty);
+ mapFaceVertices(aFi_index).Append(aVi);
+ }
+ }
+ }
+ }
+
+ // 3. Build fillet on each given vertex
+ TopoDS_Shell aResult;
+ BRep_Builder B;
+ B.MakeShell(aResult);
+
+ TopoDS_Iterator It (aFaceShape, Standard_True, Standard_True);
+ TopTools_MapOfShape mapShape;
+ for (; It.More(); It.Next()) {
+ if (mapShape.Add(It.Value())) {
+ Standard_Integer aFi_index = mapFaceVertices.FindIndex(It.Value());
+ if (aFi_index == 0) {
+ // No fillets requested on this face, add it as is
+ B.Add(aResult, It.Value());
+ }
+ else {
+ // Build a fillet and add the changed face
+ BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(It.Value()));
+ const TopTools_ListOfShape& aVertsOfFi = mapFaceVertices(aFi_index);
+ TopTools_ListIteratorOfListOfShape itV (aVertsOfFi);
+ for (; itV.More(); itV.Next()) {
+ fillet2d.AddFillet(TopoDS::Vertex(itV.Value()), rad);
+ }
+
+ fillet2d.Build();
+ if (!fillet2d.IsDone()) {
+ StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
+ }
+ TopoDS_Shape aFillet = fillet2d.Shape();
+
+ B.Add(aResult, aFillet);
+ }
+ }
+ }
- fillet2d.Build();
- if (!fillet2d.IsDone()) {
- StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
+ // 4. Build a shell
+ // ?TODO?
+ aShape = aResult;
+ }
+ else {
+ Standard_ConstructionError::Raise("Wrong arguments: a face or a shell must be given");
}
- aShape = fillet2d.Shape();
if (aShape.IsNull()) return 0;
return 1;
}
+//================================================================================
+/*!
+ * \brief Returns a name of creation operation and names and values of creation parameters
+ */
+//================================================================================
-//=======================================================================
-//function : GEOMImpl_Fillet2dDriver_Type_
-//purpose :
-//=======================================================================
-Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet2dDriver_Type_()
+bool GEOMImpl_Fillet2dDriver::
+GetCreationInformation(std::string& theOperationName,
+ std::vector<GEOM_Param>& theParams)
{
-
- static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
- if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
- static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
- if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
- static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
- if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
-
-
- static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
- static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_Fillet2dDriver",
- sizeof(GEOMImpl_Fillet2dDriver),
- 1,
- (Standard_Address)_Ancestors,
- (Standard_Address)NULL);
-
- return _aType;
-}
-
-//=======================================================================
-//function : DownCast
-//purpose :
-//=======================================================================
-const Handle(GEOMImpl_Fillet2dDriver) Handle(GEOMImpl_Fillet2dDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
-{
- Handle(GEOMImpl_Fillet2dDriver) _anOtherObject;
-
- if (!AnObject.IsNull()) {
- if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_Fillet2dDriver))) {
- _anOtherObject = Handle(GEOMImpl_Fillet2dDriver)((Handle(GEOMImpl_Fillet2dDriver)&)AnObject);
- }
+ if (Label().IsNull()) return 0;
+ Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
+
+ GEOMImpl_IFillet2d aCI( function );
+ Standard_Integer aType = function->GetType();
+
+ theOperationName = "FILLET_2D";
+
+ switch ( aType ) {
+ case FILLET_2D_SHAPE_VERTEXES:
+ AddParam( theParams, "Face", aCI.GetShape() );
+ AddParam( theParams, "Vertexes");
+ if ( aCI.GetLength() > 1 )
+ theParams[1] << aCI.GetLength() << " vertexes: ";
+ for (int i = 1; i <= aCI.GetLength(); ++i )
+ theParams[1] << aCI.GetVertex( i ) << " ";
+ AddParam( theParams, "Radius", aCI.GetR() );
+ break;
+ default:
+ return false;
}
-
- return _anOtherObject ;
+
+ return true;
}
+
+IMPLEMENT_STANDARD_HANDLE (GEOMImpl_Fillet2dDriver,GEOM_BaseDriver);
+IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_Fillet2dDriver,GEOM_BaseDriver);