Salome HOME
ffc52ae998d3a653998ec07a47b418d61393f5cf
[modules/geom.git] / src / GEOMImpl / GEOMImpl_VectorDriver.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, 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, or (at your option) any later version.
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 "GEOMImpl_VectorDriver.hxx"
24
25 #include "GEOMImpl_IVector.hxx"
26 #include "GEOMImpl_Types.hxx"
27 #include "GEOM_Function.hxx"
28 #include "GEOM_Object.hxx"
29
30 #include <BRepBuilderAPI_MakeEdge.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Precision.hxx>
35 #include <TCollection_AsciiString.hxx>
36 #include <TopAbs.hxx>
37 #include <TopExp.hxx>
38 #include <TopoDS.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <gp_Pnt.hxx>
43 #include <gp_Vec.hxx>
44
45 #include <Standard_ConstructionError.hxx>
46
47 namespace
48 {
49   Handle(GEOM_Object) GetOwner( const TDF_Label& l )
50   {
51     TDF_Label label = l;
52     // object is stored on a grandfather label of a driver label
53     if ( !label.IsNull() )
54       label = label.Father();
55     if ( !label.IsNull() )
56       label = label.Father();
57     
58     return GEOM_Object::GetObject( label );
59   }
60 }
61
62 //=======================================================================
63 //function : GetID
64 //purpose  :
65 //=======================================================================
66 const Standard_GUID& GEOMImpl_VectorDriver::GetID()
67 {
68   static Standard_GUID aVectorDriver("FF1BBB04-5D14-4df2-980B-3A668264EA16");
69   return aVectorDriver;
70 }
71
72
73 //=======================================================================
74 //function : GEOMImpl_VectorDriver
75 //purpose  :
76 //=======================================================================
77 GEOMImpl_VectorDriver::GEOMImpl_VectorDriver()
78 {
79 }
80
81 //=======================================================================
82 //function : Execute
83 //purpose  :
84 //=======================================================================
85 Standard_Integer GEOMImpl_VectorDriver::Execute(Handle(TFunction_Logbook)& log) const
86 {
87   if (Label().IsNull())  return 0;
88   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
89
90   GEOMImpl_IVector aPI (aFunction);
91   Standard_Integer aType = aFunction->GetType();
92   if (aType != VECTOR_DX_DY_DZ && aType != VECTOR_TWO_PNT &&
93       aType != VECTOR_TANGENT_CURVE_PAR && aType != VECTOR_REVERSE) return 0;
94
95   TopoDS_Shape aShape;
96
97   if (aType == VECTOR_DX_DY_DZ) {
98     gp_Pnt P1 = gp::Origin();
99     gp_Pnt P2 (aPI.GetDX(), aPI.GetDY(), aPI.GetDZ());
100     if (P1.Distance(P2) < Precision::Confusion()) {
101       TCollection_AsciiString aMsg ("Can not build vector with length, less than ");
102       aMsg += TCollection_AsciiString(Precision::Confusion());
103       Standard_ConstructionError::Raise(aMsg.ToCString());
104     }
105     aShape = BRepBuilderAPI_MakeEdge(P1, P2).Shape();
106   }
107   else if (aType == VECTOR_TWO_PNT) {
108     Handle(GEOM_Function) aRefPnt1 = aPI.GetPoint1();
109     Handle(GEOM_Function) aRefPnt2 = aPI.GetPoint2();
110     TopoDS_Shape aShape1 = aRefPnt1->GetValue();
111     TopoDS_Shape aShape2 = aRefPnt2->GetValue();
112     if (aShape1.ShapeType() != TopAbs_VERTEX ||
113         aShape2.ShapeType() != TopAbs_VERTEX) return 0;
114     if (aShape1.IsSame(aShape2)) {
115       Standard_ConstructionError::Raise("The end points must be different");
116     }
117     TopoDS_Vertex V1 = TopoDS::Vertex(aShape1);
118     TopoDS_Vertex V2 = TopoDS::Vertex(aShape2);
119     gp_Pnt P1 = BRep_Tool::Pnt(V1);
120     gp_Pnt P2 = BRep_Tool::Pnt(V2);
121     if (P1.Distance(P2) < Precision::Confusion()) {
122       Standard_ConstructionError::Raise("The end points are too close");
123     }
124     TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(V1, V2);
125     Standard_Real aTol = Max(BRep_Tool::Tolerance(V1), BRep_Tool::Tolerance(V2));
126     BRep_Builder aBuilder;
127     aBuilder.UpdateEdge(anEdge, aTol);
128     aShape = anEdge;
129   }
130   else if (aType == VECTOR_TANGENT_CURVE_PAR) {
131     Handle(GEOM_Function) aRefCurve = aPI.GetCurve();
132     TopoDS_Shape aRefShape = aRefCurve->GetValue();
133     if (aRefShape.ShapeType() != TopAbs_EDGE) {
134       Standard_TypeMismatch::Raise
135         ("Tangent On Curve creation aborted : curve shape is not an edge");
136     }
137     Standard_Real aFParam =0., aLParam =0., aParam =0.;
138     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aRefShape), aFParam, aLParam);
139     if(aCurve.IsNull()) {
140       Standard_TypeMismatch::Raise
141         ("Tangent On Curve creation aborted : curve is null");
142     }
143
144     aParam = aFParam + (aLParam - aFParam) * aPI.GetParameter();
145     gp_Pnt aPoint1,aPoint2;
146     gp_Vec aVec;
147     aCurve->D1(aParam,aPoint1,aVec);
148     if(aVec.Magnitude() < gp::Resolution())
149       Standard_TypeMismatch::Raise
150         ("Tangent On Curve creation aborted : invalid value of tangent");
151     aPoint2.SetXYZ(aPoint1.XYZ() + aVec.XYZ());
152     BRepBuilderAPI_MakeEdge aBuilder(aPoint1,aPoint2);
153     if(aBuilder.IsDone())
154       aShape = aBuilder.Shape();
155   }
156   else if (aType == VECTOR_REVERSE) {
157     Handle(GEOM_Function) aRefVec = aPI.GetCurve();
158     TopoDS_Shape aRefShape = aRefVec->GetValue();
159     if (aRefShape.ShapeType() != TopAbs_EDGE) {
160       Standard_TypeMismatch::Raise
161         ("Reversed vector creation aborted : vector shape is not an edge");
162     }
163     TopoDS_Edge anE = TopoDS::Edge(aRefShape);
164     TopoDS_Vertex V1, V2;
165     TopExp::Vertices(anE, V1, V2, Standard_True);
166     aShape = BRepBuilderAPI_MakeEdge(V2, V1).Shape();
167   }
168
169   if (aShape.IsNull()) return 0;
170
171   aFunction->SetValue(aShape);
172
173   log->SetTouched(Label());
174
175   return 1;
176 }
177
178 //================================================================================
179 /*!
180  * \brief Returns a name of creation operation and names and values of creation parameters
181  */
182 //================================================================================
183
184 bool GEOMImpl_VectorDriver::
185 GetCreationInformation(std::string&             theOperationName,
186                        std::vector<GEOM_Param>& theParams)
187 {
188   if (Label().IsNull()) return 0;
189   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
190
191   GEOMImpl_IVector aCI( function );
192   Standard_Integer aType = function->GetType();
193
194   switch ( aType ) {
195   case VECTOR_DX_DY_DZ:
196     theOperationName = "VECTOR";
197     AddParam( theParams, "Dx", aCI.GetDX() );
198     AddParam( theParams, "Dy", aCI.GetDY() );
199     AddParam( theParams, "Dz", aCI.GetDZ() );
200     break;
201   case VECTOR_TWO_PNT: {
202     Handle(GEOM_Object) obj = GetOwner( Label() );
203     if ( !obj.IsNull() && obj->GetType() == GEOM_EDGE )
204       theOperationName = "EDGE";
205     else
206       theOperationName = "VECTOR";
207     AddParam( theParams, "Point 1", aCI.GetPoint1() );
208     AddParam( theParams, "Point 2", aCI.GetPoint2() );
209     break;
210   }
211   case VECTOR_TANGENT_CURVE_PAR:
212     theOperationName = "MakeTangentOnCurve";
213     AddParam( theParams, "Curve", aCI.GetCurve() );
214     AddParam( theParams, "Parameter", aCI.GetParameter() );
215     break;
216   case VECTOR_REVERSE:
217     theOperationName = "CHANGE_ORIENTATION";
218     AddParam( theParams, "Vector", aCI.GetCurve() );
219     break;
220   default:
221     return false;
222   }
223
224   return true;
225 }
226
227 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_VectorDriver,GEOM_BaseDriver)