1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "GEOMImpl_VectorDriver.hxx"
25 #include "GEOMImpl_IVector.hxx"
26 #include "GEOMImpl_Types.hxx"
27 #include "GEOM_Function.hxx"
28 #include "GEOM_Object.hxx"
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>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Vertex.hxx>
45 #include <Standard_ConstructionError.hxx>
49 Handle(GEOM_Object) GetOwner( const TDF_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();
58 return GEOM_Object::GetObject( label );
62 //=======================================================================
65 //=======================================================================
66 const Standard_GUID& GEOMImpl_VectorDriver::GetID()
68 static Standard_GUID aVectorDriver("FF1BBB04-5D14-4df2-980B-3A668264EA16");
73 //=======================================================================
74 //function : GEOMImpl_VectorDriver
76 //=======================================================================
77 GEOMImpl_VectorDriver::GEOMImpl_VectorDriver()
81 //=======================================================================
84 //=======================================================================
85 Standard_Integer GEOMImpl_VectorDriver::Execute(Handle(TFunction_Logbook)& log) const
87 if (Label().IsNull()) return 0;
88 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
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;
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());
105 aShape = BRepBuilderAPI_MakeEdge(P1, P2).Shape();
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");
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");
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);
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");
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");
144 aParam = aFParam + (aLParam - aFParam) * aPI.GetParameter();
145 gp_Pnt aPoint1,aPoint2;
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();
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");
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();
169 if (aShape.IsNull()) return 0;
171 aFunction->SetValue(aShape);
173 log->SetTouched(Label());
178 //================================================================================
180 * \brief Returns a name of creation operation and names and values of creation parameters
182 //================================================================================
184 bool GEOMImpl_VectorDriver::
185 GetCreationInformation(std::string& theOperationName,
186 std::vector<GEOM_Param>& theParams)
188 if (Label().IsNull()) return 0;
189 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
191 GEOMImpl_IVector aCI( function );
192 Standard_Integer aType = function->GetType();
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() );
201 case VECTOR_TWO_PNT: {
202 Handle(GEOM_Object) obj = GetOwner( Label() );
203 if ( !obj.IsNull() && obj->GetType() == GEOM_EDGE )
204 theOperationName = "EDGE";
206 theOperationName = "VECTOR";
207 AddParam( theParams, "Point 1", aCI.GetPoint1() );
208 AddParam( theParams, "Point 2", aCI.GetPoint2() );
211 case VECTOR_TANGENT_CURVE_PAR:
212 theOperationName = "MakeTangentOnCurve";
213 AddParam( theParams, "Curve", aCI.GetCurve() );
214 AddParam( theParams, "Parameter", aCI.GetParameter() );
217 theOperationName = "CHANGE_ORIENTATION";
218 AddParam( theParams, "Vector", aCI.GetCurve() );
227 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_VectorDriver,GEOM_BaseDriver)