Back to index

salome-geom  6.5.0
GEOMImpl_ProjectionDriver.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_ProjectionDriver.hxx>
00026 
00027 #include <GEOMImpl_IMirror.hxx>
00028 #include <GEOMImpl_Types.hxx>
00029 #include <GEOM_Function.hxx>
00030 
00031 #include <BRep_Tool.hxx>
00032 #include <BRepBuilderAPI_Transform.hxx>
00033 #include <BRepBuilderAPI_MakeVertex.hxx>
00034 #include <BRepClass_FaceClassifier.hxx>
00035 #include <BRepOffsetAPI_NormalProjection.hxx>
00036 #include <BRepTools.hxx>
00037 
00038 #include <TopAbs.hxx>
00039 #include <TopExp.hxx>
00040 #include <TopoDS.hxx>
00041 #include <TopoDS_Shape.hxx>
00042 #include <TopoDS_Edge.hxx>
00043 #include <TopoDS_Face.hxx>
00044 #include <TopoDS_Vertex.hxx>
00045 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00046 
00047 #include <GeomAPI_ProjectPointOnSurf.hxx>
00048 #include <Geom_Plane.hxx>
00049 
00050 #include <gp_Trsf.hxx>
00051 #include <gp_Pnt.hxx>
00052 #include <gp_Vec.hxx>
00053 
00054 //=======================================================================
00055 //function : GetID
00056 //purpose  :
00057 //======================================================================= 
00058 const Standard_GUID& GEOMImpl_ProjectionDriver::GetID()
00059 {
00060   static Standard_GUID aProjectionDriver ("FF1BBB70-5D14-4df2-980B-3A668264EA16");
00061   return aProjectionDriver; 
00062 }
00063 
00064 
00065 //=======================================================================
00066 //function : GEOMImpl_ProjectionDriver
00067 //purpose  : 
00068 //=======================================================================
00069 
00070 GEOMImpl_ProjectionDriver::GEOMImpl_ProjectionDriver() 
00071 {
00072 }
00073 
00074 //=======================================================================
00075 //function : Execute
00076 //purpose  :
00077 //======================================================================= 
00078 Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) const
00079 {
00080   if (Label().IsNull())  return 0;    
00081   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
00082 
00083   if (aFunction.IsNull()) return 0;
00084 
00085   TopoDS_Shape aShape;
00086   gp_Trsf aTrsf;
00087 
00088   GEOMImpl_IMirror TI (aFunction);
00089   Standard_Integer aType = aFunction->GetType();
00090 
00091   Handle(GEOM_Function) anOriginalFunction = TI.GetOriginal();
00092   if (anOriginalFunction.IsNull()) return 0;
00093 
00094   TopoDS_Shape anOriginal = anOriginalFunction->GetValue();
00095   if (anOriginal.IsNull()) return 0;
00096 
00097   // Projection
00098   if (aType == PROJECTION_COPY) {
00099     // Source shape (point, edge or wire)
00100     if (anOriginal.ShapeType() != TopAbs_VERTEX &&
00101         anOriginal.ShapeType() != TopAbs_EDGE &&
00102         anOriginal.ShapeType() != TopAbs_WIRE) {
00103       Standard_ConstructionError::Raise
00104         ("Projection aborted : the source shape is neither a vertex, nor an edge or a wire");
00105     }
00106 
00107     // Target face
00108     Handle(GEOM_Function) aTargetFunction = TI.GetPlane();
00109     if (aTargetFunction.IsNull()) return 0;
00110     TopoDS_Shape aFaceShape = aTargetFunction->GetValue();
00111     //if (aFaceShape.IsNull() || aFaceShape.ShapeType() != TopAbs_FACE) {
00112     //  Standard_ConstructionError::Raise
00113     //    ("Projection aborted : the target shape is not a face");
00114     //}
00115 
00116     Standard_Real tol = 1.e-4;        
00117 
00118     if (anOriginal.ShapeType() == TopAbs_VERTEX) {
00119       if (aFaceShape.IsNull() || aFaceShape.ShapeType() != TopAbs_FACE) {
00120         Standard_ConstructionError::Raise
00121           ("Projection aborted : the target shape is not a face");
00122       }
00123       TopoDS_Face aFace = TopoDS::Face(aFaceShape);
00124       Handle(Geom_Surface) surface = BRep_Tool::Surface(aFace);
00125       double U1, U2, V1, V2;
00126       //surface->Bounds(U1, U2, V1, V2);
00127       BRepTools::UVBounds(aFace, U1, U2, V1, V2);
00128 
00129       // projector
00130       GeomAPI_ProjectPointOnSurf proj;
00131       proj.Init(surface, U1, U2, V1, V2, tol);
00132 
00133       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(anOriginal));
00134       proj.Perform(aPnt);
00135       if (!proj.IsDone()) {
00136         Standard_ConstructionError::Raise
00137           ("Projection aborted : the algorithm failed");
00138       }
00139       int nbPoints = proj.NbPoints();
00140       if (nbPoints < 1) {
00141         Standard_ConstructionError::Raise("No solution found");
00142       }
00143 
00144       Quantity_Parameter U, V;
00145       proj.LowerDistanceParameters(U, V);
00146       gp_Pnt2d aProjPnt (U, V);
00147 
00148       // classifier
00149       BRepClass_FaceClassifier aClsf (aFace, aProjPnt, tol);
00150       if (aClsf.State() != TopAbs_IN && aClsf.State() != TopAbs_ON) {
00151         bool isSol = false;
00152         double minDist = RealLast();
00153         for (int i = 1; i <= nbPoints; i++) {
00154           Quantity_Parameter Ui, Vi;
00155           proj.Parameters(i, Ui, Vi);
00156           aProjPnt = gp_Pnt2d(Ui, Vi);
00157           aClsf.Perform(aFace, aProjPnt, tol);
00158           if (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON) {
00159             isSol = true;
00160             double dist = proj.Distance(i);
00161             if (dist < minDist) {
00162               minDist = dist;
00163               U = Ui;
00164               V = Vi;
00165             }
00166           }
00167         }
00168         if (!isSol) {
00169           Standard_ConstructionError::Raise("No solution found");
00170         }
00171       }
00172 
00173       gp_Pnt surfPnt = surface->Value(U, V);
00174 
00175       aShape = BRepBuilderAPI_MakeVertex(surfPnt).Shape();
00176     }
00177     else {
00178       //see BRepTest_BasicCommands.cxx for example of BRepOffsetAPI_NormalProjection
00179       BRepOffsetAPI_NormalProjection OrtProj (aFaceShape);
00180       OrtProj.Add(anOriginal);
00181 
00182       //Standard_Real tol = 1.e-4;        
00183       //Standard_Real tol2d = Pow(tol, 2./3);
00184       //GeomAbs_Shape Continuity = GeomAbs_C2;  
00185       //Standard_Integer MaxDeg = 14;           
00186       //Standard_Integer MaxSeg = 16;           
00187       //OrtProj.SetParams(tol, tol2d, Continuity, MaxDeg, MaxSeg);
00188       try {
00189         OrtProj.Build();
00190       } catch (Standard_Failure) {
00191         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00192         TCollection_AsciiString aMsg (aFail->GetMessageString());
00193         if (!aMsg.Length())
00194           aMsg = "Projection aborted : possibly the source shape intersects the cylinder's axis";
00195         Standard_ConstructionError::Raise(aMsg.ToCString());
00196       }
00197       if (!OrtProj.IsDone()) {
00198         Standard_ConstructionError::Raise
00199           ("Projection aborted : BRepOffsetAPI_NormalProjection failed");
00200       }
00201 
00202       aShape = OrtProj.Shape();
00203 
00204       // check that the result shape is an empty compound
00205       // (IPAL22905: TC650: Projection on face dialog problems)
00206       if( !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND )
00207       {
00208         TopoDS_Iterator anIter( aShape );
00209         if( !anIter.More() )
00210           Standard_ConstructionError::Raise("Projection aborted : empty compound produced");
00211       }
00212     }
00213 
00214     if (aShape.IsNull()) return 0;
00215 
00216     aFunction->SetValue(aShape);
00217     log.SetTouched(Label()); 
00218   }
00219 
00220   return 1;
00221 }
00222 
00223 
00224 //=======================================================================
00225 //function :  GEOMImpl_ProjectionDriver_Type_
00226 //purpose  :
00227 //======================================================================= 
00228 Standard_EXPORT Handle_Standard_Type& GEOMImpl_ProjectionDriver_Type_()
00229 {
00230 
00231   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
00232   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
00233   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
00234   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); 
00235   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
00236   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
00237  
00238 
00239   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
00240   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_ProjectionDriver",
00241                                                          sizeof(GEOMImpl_ProjectionDriver),
00242                                                          1,
00243                                                          (Standard_Address)_Ancestors,
00244                                                          (Standard_Address)NULL);
00245 
00246   return _aType;
00247 }
00248 
00249 //=======================================================================
00250 //function : DownCast
00251 //purpose  :
00252 //======================================================================= 
00253 
00254 const Handle(GEOMImpl_ProjectionDriver) Handle(GEOMImpl_ProjectionDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
00255 {
00256   Handle(GEOMImpl_ProjectionDriver) _anOtherObject;
00257 
00258   if (!AnObject.IsNull()) {
00259      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_ProjectionDriver))) {
00260        _anOtherObject = Handle(GEOMImpl_ProjectionDriver)((Handle(GEOMImpl_ProjectionDriver)&)AnObject);
00261      }
00262   }
00263 
00264   return _anOtherObject;
00265 }