Back to index

salome-geom  6.5.0
BlockFix.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 // File:        BlockFix.cxx
00023 // Created:     Tue Dec  7 11:59:05 2004
00024 // Author:      Pavel DURANDIN
00025 
00026 #include <BlockFix.hxx>
00027 
00028 #include <BlockFix_SphereSpaceModifier.hxx>
00029 #include <BlockFix_PeriodicSurfaceModifier.hxx>
00030 
00031 #include <TopExp.hxx>
00032 #include <TopExp_Explorer.hxx>
00033 
00034 #include <TopLoc_Location.hxx>
00035 
00036 #include <TopoDS.hxx>
00037 #include <TopoDS_Edge.hxx>
00038 #include <TopoDS_Face.hxx>
00039 #include <TopoDS_Wire.hxx>
00040 #include <TopoDS_Shape.hxx>
00041 #include <TopoDS_Solid.hxx>
00042 #include <TopoDS_Vertex.hxx>
00043 
00044 #include <TopTools_ListOfShape.hxx>
00045 #include <TopTools_ListIteratorOfListOfShape.hxx>
00046 #include <TopTools_MapOfShape.hxx>
00047 #include <TopTools_DataMapOfShapeShape.hxx>
00048 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
00049 
00050 #include <BRep_Tool.hxx>
00051 #include <BRep_Builder.hxx>
00052 
00053 #include <BRepAdaptor_Surface.hxx>
00054 
00055 #include <BRepTools.hxx>
00056 #include <BRepTools_Modifier.hxx>
00057 #include <BRepTools_Substitution.hxx>
00058 
00059 #include <BRepOffsetAPI_MakeFilling.hxx>
00060 
00061 #include <ShapeFix.hxx>
00062 #include <ShapeFix_Edge.hxx>
00063 #include <ShapeFix_Face.hxx>
00064 
00065 #include <ShapeAnalysis.hxx>
00066 #include <ShapeAnalysis_Edge.hxx>
00067 #include <ShapeAnalysis_Curve.hxx>
00068 #include <ShapeAnalysis_Surface.hxx>
00069 
00070 #include <ShapeCustom.hxx>
00071 
00072 #include <ShapeBuild_Edge.hxx>
00073 #include <ShapeBuild_ReShape.hxx>
00074 
00075 #include <ShapeFix_Wire.hxx>
00076 
00077 #include <Geom_Surface.hxx>
00078 #include <Geom_CylindricalSurface.hxx>
00079 #include <Geom_ConicalSurface.hxx>
00080 #include <Geom_SphericalSurface.hxx>
00081 #include <Geom_ToroidalSurface.hxx>
00082 
00083 #include <Geom2d_Curve.hxx>
00084 
00085 #include <TColgp_SequenceOfPnt2d.hxx>
00086 
00087 //=======================================================================
00088 //function : FixResult
00089 //purpose  : auxilary
00090 //=======================================================================
00091 static void FixResult(const TopoDS_Shape& result,
00092                       Handle(ShapeBuild_ReShape)& Context,
00093                       const Standard_Real Tol)
00094 {
00095   for (TopExp_Explorer ex_f(result,TopAbs_FACE); ex_f.More(); ex_f.Next()) {
00096     TopoDS_Shape aShape = Context->Apply(ex_f.Current().Oriented(TopAbs_FORWARD));
00097     // face coud not be dropped or splitted on this step
00098     TopoDS_Face aFace = TopoDS::Face(aShape);
00099     TopLoc_Location L;
00100     Handle(Geom_Surface) Surf = BRep_Tool::Surface(aFace,L);
00101 
00102     if( Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
00103         Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ) {
00104 
00105       Standard_Integer nbWires = 0;
00106       for (TopExp_Explorer ex_w(aFace,TopAbs_WIRE); ex_w.More(); ex_w.Next()) {
00107         nbWires++;
00108         Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(TopoDS::Wire(ex_w.Current()),
00109                                                       aFace,
00110                                                       Precision::Confusion());
00111         sfw->FixReorder();
00112         if(sfw->StatusReorder ( ShapeExtend_FAIL ))
00113           continue;
00114 
00115         sfw->SetPrecision(2.*Tol);
00116         sfw->FixShifted();
00117 
00118         Standard_Boolean isDone = sfw->LastFixStatus ( ShapeExtend_DONE );
00119         isDone |= sfw->FixDegenerated();
00120 
00121         // remove degenerated edges from not degenerated points
00122         ShapeAnalysis_Edge sae;
00123         Handle(ShapeExtend_WireData) sewd = sfw->WireData();
00124         Standard_Integer i;
00125         for( i = 1; i<=sewd->NbEdges();i++) {
00126           TopoDS_Edge E = sewd->Edge(i);
00127           if(BRep_Tool::Degenerated(E)&&!sae.HasPCurve(E,aFace)) {
00128             sewd->Remove(i);
00129             isDone = Standard_True;
00130             i--;
00131           }
00132         }
00133 
00134         //isDone |= sfw->FixLacking(); // commented by skl 22.03.2005 (PAL8395)
00135 
00136         // remove neighbour seam edges
00137         if(isDone) {
00138           for( i = 1; i<sewd->NbEdges();i++) {
00139             if(sewd->IsSeam(i) && sewd->IsSeam(i+1)) {
00140               isDone = Standard_True;
00141               sewd->Remove(i);
00142               sewd->Remove(i);
00143               i--;
00144             }
00145           }
00146           if(sewd->IsSeam(1) && sewd->IsSeam(sewd->NbEdges())) {
00147             sewd->Remove(1);
00148             sewd->Remove(sewd->NbEdges());
00149           }
00150         }
00151 
00152         if(isDone) {
00153           TopoDS_Wire ResWire = sfw->Wire();
00154           Context->Replace(ex_w.Current(), ResWire);
00155         };
00156       }
00157       // Implement fix orientation in case of several wires
00158       if(nbWires > 1) {
00159         TopoDS_Face aFixedFace = TopoDS::Face(Context->Apply(aFace));
00160         Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFixedFace);
00161         if(sff->FixOrientation())
00162           Context->Replace(aFixedFace,sff->Face());
00163       }
00164     }
00165   }
00166 }
00167 
00168 //=======================================================================
00169 //function : RotateSphereSpace
00170 //purpose  :
00171 //=======================================================================
00172 TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
00173                                           const Standard_Real Tol)
00174 {
00175   // Create a modification description
00176   Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
00177   SR->SetTolerance(Tol);
00178 
00179   TopTools_DataMapOfShapeShape context;
00180   BRepTools_Modifier MD;
00181   TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
00182 
00183   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
00184   FixResult(result,RS,Tol);
00185   result = RS->Apply(result);
00186 
00187   ShapeFix_Edge sfe;
00188   for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
00189     TopoDS_Edge E = TopoDS::Edge(exp.Current());
00190     sfe.FixVertexTolerance (E);
00191   }
00192 
00193   ShapeFix::SameParameter(result,Standard_False);
00194   return result;
00195 }
00196 
00197 //=======================================================================
00198 //function : RefillProblemFaces
00199 //purpose  :
00200 //=======================================================================
00201 TopoDS_Shape BlockFix::RefillProblemFaces (const TopoDS_Shape& aShape)
00202 {
00203   Standard_Integer NbSamples = 10;
00204 
00205   TopTools_ListOfShape theFaces;
00206 
00207   TopExp_Explorer Explo(aShape, TopAbs_FACE);
00208   for (; Explo.More(); Explo.Next())
00209   {
00210     TopoDS_Face aFace = TopoDS::Face(Explo.Current());
00211     BRepAdaptor_Surface BAsurf(aFace);
00212     GeomAbs_SurfaceType SurfType = BAsurf.GetType();
00213     if (SurfType >= GeomAbs_BezierSurface)
00214     {
00215       TopExp_Explorer fexp(aFace, TopAbs_EDGE);
00216       for (; fexp.More(); fexp.Next())
00217       {
00218         const TopoDS_Edge& anEdge = TopoDS::Edge(fexp.Current());
00219         if (BRep_Tool::Degenerated(anEdge))
00220         {
00221           TopoDS_Vertex V1, V2;
00222           TopExp::Vertices(anEdge, V1, V2);
00223           if (V1.IsSame(V2))
00224           {
00225             gp_Pnt aPnt = BRep_Tool::Pnt(V1);
00226             Standard_Real TolV = BRep_Tool::Tolerance(V1);
00227             Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
00228             Handle(ShapeAnalysis_Surface) Analyser = new ShapeAnalysis_Surface(aSurf);
00229             if (Analyser->IsDegenerated(aPnt, TolV))
00230             {
00231               theFaces.Append(aFace);
00232               break;
00233             }
00234           }
00235         }
00236       }
00237     }
00238   }
00239 
00240   //Now all problem faces are collected in the list "theFaces"
00241   BRepTools_Substitution aSubst;
00242   TopTools_ListIteratorOfListOfShape itl(theFaces);
00243   for (; itl.More(); itl.Next())
00244   {
00245     const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
00246     BRepOffsetAPI_MakeFilling Filler;
00247     for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
00248     {
00249       const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
00250       if (!BRep_Tool::Degenerated(anEdge))
00251         Filler.Add(anEdge, GeomAbs_C0);
00252     }
00253     Standard_Real Umin, Umax, Vmin, Vmax;
00254     BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
00255     //Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
00256     Standard_Integer i, j;
00257     for (i = 1; i < NbSamples; i++)
00258       for (j = 1; j < NbSamples; j++) {
00259         /*
00260         gp_Pnt aPoint = aSurf->Value(Umin + i*(Umax-Umin)/NbSamples,
00261                                      Vmin + j*(Vmax-Vmin)/NbSamples);
00262         Filler.Add(aPoint);
00263         */
00264         Filler.Add(Umin + i*(Umax-Umin)/NbSamples,
00265                    Vmin + j*(Vmax-Vmin)/NbSamples,
00266                    aFace, GeomAbs_G1);
00267       }
00268 
00269     Filler.Build();
00270     if (Filler.IsDone())
00271     {
00272       for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
00273       {
00274         const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
00275         TopTools_ListOfShape Ledge;
00276         if (!BRep_Tool::Degenerated(anEdge))
00277         {
00278           const TopTools_ListOfShape& Ledges = Filler.Generated(anEdge);
00279           if (!Ledges.IsEmpty()) {
00280             TopoDS_Shape NewEdge = Ledges.First();
00281             Ledge.Append(NewEdge.Oriented(TopAbs_FORWARD));
00282           }
00283         }
00284         aSubst.Substitute(anEdge, Ledge);
00285       }
00286       TopTools_ListOfShape Lface;
00287       TopoDS_Face NewFace = TopoDS::Face(Filler.Shape());
00288       NewFace.Orientation(TopAbs_FORWARD);
00289       BRepAdaptor_Surface NewBAsurf(NewFace);
00290       gp_Pnt MidPnt;
00291       gp_Vec D1U, D1V, Normal, NewNormal;
00292       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
00293       aSurf->D1((Umin+Umax)*0.5, (Vmin+Vmax)*0.5, MidPnt, D1U, D1V);
00294       Normal = D1U ^ D1V;
00295       NewBAsurf.D1((NewBAsurf.FirstUParameter() + NewBAsurf.LastUParameter())*0.5,
00296                    (NewBAsurf.FirstVParameter() + NewBAsurf.LastVParameter())*0.5,
00297                    MidPnt, D1U, D1V);
00298       NewNormal = D1U ^ D1V;
00299       if (Normal * NewNormal < 0.)
00300         NewFace.Reverse();
00301       Lface.Append(NewFace);
00302       aSubst.Substitute(aFace, Lface);
00303     }
00304   }
00305   aSubst.Build(aShape);
00306 
00307   TopoDS_Shape Result = aShape;
00308   if (aSubst.IsCopied(aShape))
00309     Result = aSubst.Copy(aShape).First();
00310 
00311   BRepTools::RemoveUnusedPCurves(Result);
00312 
00313   return Result;
00314 }
00315 
00316 //=======================================================================
00317 //function : FixRanges
00318 //purpose  :
00319 //=======================================================================
00320 TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
00321                                   const Standard_Real Tol)
00322 {
00323   // Create a modification description
00324   Handle(BlockFix_PeriodicSurfaceModifier) SR = new BlockFix_PeriodicSurfaceModifier;
00325   SR->SetTolerance(Tol);
00326 
00327   TopTools_DataMapOfShapeShape context;
00328   BRepTools_Modifier MD;
00329   TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
00330 
00331   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
00332   FixResult(result,RS,Tol);
00333   result = RS->Apply(result);
00334 
00335   ShapeFix_Edge sfe;
00336   for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
00337     TopoDS_Edge E = TopoDS::Edge(exp.Current());
00338     sfe.FixVertexTolerance (E);
00339   }
00340 
00341   ShapeFix::SameParameter(result,Standard_False);
00342 
00343   return result;
00344 }