]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx
Salome HOME
0021684: EDF 2221 : Display the arguments and the name of the operations
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ProjectionDriver.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <Standard_Stream.hxx>
24
25 #include <GEOMImpl_ProjectionDriver.hxx>
26
27 #include <GEOMImpl_IMirror.hxx>
28 #include <GEOMImpl_Types.hxx>
29 #include <GEOM_Function.hxx>
30
31 #include <BRep_Tool.hxx>
32 #include <BRepBuilderAPI_Transform.hxx>
33 #include <BRepBuilderAPI_MakeVertex.hxx>
34 #include <BRepClass_FaceClassifier.hxx>
35 #include <BRepOffsetAPI_NormalProjection.hxx>
36 #include <BRepTools.hxx>
37
38 #include <TopAbs.hxx>
39 #include <TopExp.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Vertex.hxx>
45 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46
47 #include <GeomAPI_ProjectPointOnSurf.hxx>
48 #include <Geom_Plane.hxx>
49
50 #include <gp_Trsf.hxx>
51 #include <gp_Pnt.hxx>
52 #include <gp_Vec.hxx>
53
54 //=======================================================================
55 //function : GetID
56 //purpose  :
57 //======================================================================= 
58 const Standard_GUID& GEOMImpl_ProjectionDriver::GetID()
59 {
60   static Standard_GUID aProjectionDriver ("FF1BBB70-5D14-4df2-980B-3A668264EA16");
61   return aProjectionDriver; 
62 }
63
64
65 //=======================================================================
66 //function : GEOMImpl_ProjectionDriver
67 //purpose  : 
68 //=======================================================================
69
70 GEOMImpl_ProjectionDriver::GEOMImpl_ProjectionDriver() 
71 {
72 }
73
74 //=======================================================================
75 //function : Execute
76 //purpose  :
77 //======================================================================= 
78 Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) const
79 {
80   if (Label().IsNull())  return 0;    
81   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
82
83   if (aFunction.IsNull()) return 0;
84
85   TopoDS_Shape aShape;
86   gp_Trsf aTrsf;
87
88   GEOMImpl_IMirror TI (aFunction);
89   Standard_Integer aType = aFunction->GetType();
90
91   Handle(GEOM_Function) anOriginalFunction = TI.GetOriginal();
92   if (anOriginalFunction.IsNull()) return 0;
93
94   TopoDS_Shape anOriginal = anOriginalFunction->GetValue();
95   if (anOriginal.IsNull()) return 0;
96
97   // Projection
98   if (aType == PROJECTION_COPY) {
99     // Source shape (point, edge or wire)
100     if (anOriginal.ShapeType() != TopAbs_VERTEX &&
101         anOriginal.ShapeType() != TopAbs_EDGE &&
102         anOriginal.ShapeType() != TopAbs_WIRE) {
103       Standard_ConstructionError::Raise
104         ("Projection aborted : the source shape is neither a vertex, nor an edge or a wire");
105     }
106
107     // Target face
108     Handle(GEOM_Function) aTargetFunction = TI.GetPlane();
109     if (aTargetFunction.IsNull()) return 0;
110     TopoDS_Shape aFaceShape = aTargetFunction->GetValue();
111     //if (aFaceShape.IsNull() || aFaceShape.ShapeType() != TopAbs_FACE) {
112     //  Standard_ConstructionError::Raise
113     //    ("Projection aborted : the target shape is not a face");
114     //}
115
116     Standard_Real tol = 1.e-4;        
117
118     if (anOriginal.ShapeType() == TopAbs_VERTEX) {
119       if (aFaceShape.IsNull() || aFaceShape.ShapeType() != TopAbs_FACE) {
120         Standard_ConstructionError::Raise
121           ("Projection aborted : the target shape is not a face");
122       }
123       TopoDS_Face aFace = TopoDS::Face(aFaceShape);
124       Handle(Geom_Surface) surface = BRep_Tool::Surface(aFace);
125       double U1, U2, V1, V2;
126       //surface->Bounds(U1, U2, V1, V2);
127       BRepTools::UVBounds(aFace, U1, U2, V1, V2);
128
129       // projector
130       GeomAPI_ProjectPointOnSurf proj;
131       proj.Init(surface, U1, U2, V1, V2, tol);
132
133       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(anOriginal));
134       proj.Perform(aPnt);
135       if (!proj.IsDone()) {
136         Standard_ConstructionError::Raise
137           ("Projection aborted : the algorithm failed");
138       }
139       int nbPoints = proj.NbPoints();
140       if (nbPoints < 1) {
141         Standard_ConstructionError::Raise("No solution found");
142       }
143
144       Quantity_Parameter U, V;
145       proj.LowerDistanceParameters(U, V);
146       gp_Pnt2d aProjPnt (U, V);
147
148       // classifier
149       BRepClass_FaceClassifier aClsf (aFace, aProjPnt, tol);
150       if (aClsf.State() != TopAbs_IN && aClsf.State() != TopAbs_ON) {
151         bool isSol = false;
152         double minDist = RealLast();
153         for (int i = 1; i <= nbPoints; i++) {
154           Quantity_Parameter Ui, Vi;
155           proj.Parameters(i, Ui, Vi);
156           aProjPnt = gp_Pnt2d(Ui, Vi);
157           aClsf.Perform(aFace, aProjPnt, tol);
158           if (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON) {
159             isSol = true;
160             double dist = proj.Distance(i);
161             if (dist < minDist) {
162               minDist = dist;
163               U = Ui;
164               V = Vi;
165             }
166           }
167         }
168         if (!isSol) {
169           Standard_ConstructionError::Raise("No solution found");
170         }
171       }
172
173       gp_Pnt surfPnt = surface->Value(U, V);
174
175       aShape = BRepBuilderAPI_MakeVertex(surfPnt).Shape();
176     }
177     else {
178       //see BRepTest_BasicCommands.cxx for example of BRepOffsetAPI_NormalProjection
179       BRepOffsetAPI_NormalProjection OrtProj (aFaceShape);
180       OrtProj.Add(anOriginal);
181
182       //Standard_Real tol = 1.e-4;        
183       //Standard_Real tol2d = Pow(tol, 2./3);
184       //GeomAbs_Shape Continuity = GeomAbs_C2;  
185       //Standard_Integer MaxDeg = 14;           
186       //Standard_Integer MaxSeg = 16;           
187       //OrtProj.SetParams(tol, tol2d, Continuity, MaxDeg, MaxSeg);
188       try {
189         OrtProj.Build();
190       } catch (Standard_Failure) {
191         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
192         TCollection_AsciiString aMsg (aFail->GetMessageString());
193         if (!aMsg.Length())
194           aMsg = "Projection aborted : possibly the source shape intersects the cylinder's axis";
195         Standard_ConstructionError::Raise(aMsg.ToCString());
196       }
197       if (!OrtProj.IsDone()) {
198         Standard_ConstructionError::Raise
199           ("Projection aborted : BRepOffsetAPI_NormalProjection failed");
200       }
201
202       aShape = OrtProj.Shape();
203
204       // check that the result shape is an empty compound
205       // (IPAL22905: TC650: Projection on face dialog problems)
206       if( !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND )
207       {
208         TopoDS_Iterator anIter( aShape );
209         if( !anIter.More() )
210           Standard_ConstructionError::Raise("Projection aborted : empty compound produced");
211       }
212     }
213
214     if (aShape.IsNull()) return 0;
215
216     aFunction->SetValue(aShape);
217     log.SetTouched(Label()); 
218   }
219
220   return 1;
221 }
222
223 //================================================================================
224 /*!
225  * \brief Returns a name of creation operation and names and values of creation parameters
226  */
227 //================================================================================
228
229 bool GEOMImpl_ProjectionDriver::
230 GetCreationInformation(std::string&             theOperationName,
231                        std::vector<GEOM_Param>& theParams)
232 {
233   if (Label().IsNull()) return 0;
234   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
235
236   GEOMImpl_IMirror aCI( function );
237   Standard_Integer aType = function->GetType();
238
239   theOperationName = "PROJECTION";
240
241   switch ( aType ) {
242   case PROJECTION_COPY:
243     AddParam( theParams, "Source object", aCI.GetOriginal() );
244     AddParam( theParams, "Target face", aCI.GetPlane() );
245     break;
246   default:
247     return false;
248   }
249   
250   return true;
251 }
252
253 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ProjectionDriver,GEOM_BaseDriver);
254 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ProjectionDriver,GEOM_BaseDriver);