Salome HOME
Changes for 0020673 - Implementation of "Auto-correct edges orientation".
[modules/geom.git] / src / GEOMImpl / GEOMImpl_Fillet1dDriver.cxx
index fc54a402b7ff66dbacf1e1bda7606db8afc114ea..19b6b2d7a79d519fe9d7b3bd03a9a418105d82dd 100644 (file)
@@ -26,6 +26,7 @@
 #include <GEOMImpl_IFillet1d.hxx>
 #include <GEOMImpl_Types.hxx>
 #include <GEOMImpl_ILocalOperations.hxx>
+#include <GEOMImpl_IShapesOperations.hxx>
 #include <GEOM_Function.hxx>
 
 #include <gp_Pln.hxx>
@@ -119,8 +120,7 @@ static Standard_Boolean takePlane( const TopoDS_Edge& theE1,
     if ( fabs(anAngle) <= gp::Resolution() || 
          fabs(anAngle - PI) <= gp::Resolution() )
       return false;
-    //thePlane = gp_Pln( gp_Pnt(aXYZ), aDir1^ aDir2);
-    thePlane = gp_Pln( gp_Pnt(aXYZ), gp_Dir(0,0,1));
+    thePlane = gp_Pln( gp_Pnt(aXYZ), aDir1^ aDir2);
   }
   catch (Standard_Failure) {
     return false;
@@ -155,6 +155,8 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
 
   Handle(GEOM_Function) aRefShape = aCI.GetShape();
   TopoDS_Shape aShape = aRefShape->GetValue();
+  if (aShape.IsNull())
+    return 0;
   if (aShape.ShapeType() != TopAbs_WIRE)
     Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");
 
@@ -162,29 +164,31 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
 
   double rad = aCI.GetR();
 
+  if ( rad < Precision::Confusion())
+    return 0;
+
   // collect vertices for make fillet
   TopTools_ListOfShape aVertexList;
+  TopTools_MapOfShape mapShape;
   int aLen = aCI.GetLength();
-  if ( aLen > 0 )
-  {
+  if ( aLen > 0 ) {
     for (int ind = 1; ind <= aLen; ind++) {
       TopoDS_Shape aShapeVertex;
       if (GEOMImpl_ILocalOperations::GetSubShape
-         (aWire, aCI.GetVertex(ind), aShapeVertex))
-        aVertexList.Append( aShapeVertex );
+          (aWire, aCI.GetVertex(ind), aShapeVertex))
+        if (mapShape.Add(aShapeVertex))
+          aVertexList.Append( aShapeVertex );
+    }
+  } else { // get all vertices from wire
+    TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
+    for ( ; anExp.More(); anExp.Next() ) {
+      if (mapShape.Add(anExp.Current()))
+        aVertexList.Append( anExp.Current() );
     }
-  }
-  else
-  {
-     // get all vertices from wire
-     TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
-     for ( ; anExp.More(); anExp.Next() )
-       aVertexList.Append( anExp.Current() );
   }
   if (aVertexList.IsEmpty())
     Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");
 
-  bool res = false;
   //INFO: this algorithm implemented in assumption that user can select both
   //  vertices of some edges to make fillet. In this case we should remember
   //  already modified initial edges to take care in next fillet step
@@ -197,8 +201,7 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
   TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
   TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
   TopTools_ListIteratorOfListOfShape anIt( aVertexList );
-  for ( ; anIt.More(); anIt.Next() )
-  {
+  for ( ; anIt.More(); anIt.Next() ) {
     TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
     if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
       continue;
@@ -228,33 +231,33 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
     if (aNewE.IsNull())
       continue; // no result found
     
-    res |= true;
     // add  new created edges and take modified edges
     aListOfNewEdge.Append( aNewE );
     
     // check if face edges modified,
-    //  if yes, than map to original edges (from vertex-edges list), because edges can be modified before
-    if (!aModifE1.IsNull() || !aModifE1.IsSame( anEdge1 ))
+    // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
+    if (!aModifE1.IsNull() && !aModifE1.IsSame( anEdge1 ))
       addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
-    if (!aModifE2.IsNull() || !aModifE2.IsSame( anEdge2 ))
+    if (!aModifE2.IsNull() && !aModifE2.IsSame( anEdge2 ))
       addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
   }
 
-  if ( !res && anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() )
-  {
+  if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) {
     StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
-    return 0; // nothing done :(
+    return 0;
   }
   
   // create new wire instead of original
-  for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() )
-  {
-    TopoDS_Shape anEdge = anExp.Current();
+  for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
+    TopoDS_Shape anEdge = anExp.Current(); 
     if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
       aListOfNewEdge.Append( anEdge );
     else
       aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
   }
+
+  GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge );
+
   BRepBuilderAPI_MakeWire aWireTool;
   aWireTool.Add( aListOfNewEdge );
   aWireTool.Build();
@@ -286,10 +289,10 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet1dDriver_Type_()
 
   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_Fillet1dDriver",
-                                                        sizeof(GEOMImpl_Fillet1dDriver),
-                                                        1,
-                                                        (Standard_Address)_Ancestors,
-                                                        (Standard_Address)NULL);
+                                                         sizeof(GEOMImpl_Fillet1dDriver),
+                                                         1,
+                                                         (Standard_Address)_Ancestors,
+                                                         (Standard_Address)NULL);
 
   return _aType;
 }