/src/contrib/geom-5.1.2.7/src/GEOMImpl/GEOMImpl_RevolutionDriver.cpp

http://pythonocc.googlecode.com/ · C++ · 522 lines · 383 code · 81 blank · 58 comment · 68 complexity · c685dc8f16ed3bd3c169b4f9c52ccde8 MD5 · raw file

  1. // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
  2. // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License.
  8. //
  9. // This library is distributed in the hope that it will be useful
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. //
  18. // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
  19. //
  20. #include "utilities.h"
  21. #include <Standard_Stream.hxx>
  22. #include <GEOMImpl_RevolutionDriver.hxx>
  23. #include <GEOMImpl_IShapesOperations.hxx>
  24. #include <GEOMImpl_IRevolution.hxx>
  25. #include <GEOMImpl_Types.hxx>
  26. #include <GEOM_Function.hxx>
  27. #include <BRepPrimAPI_MakeRevol.hxx>
  28. #include <BRepBuilderAPI_MakeEdge.hxx>
  29. #include <BRepBuilderAPI_MakeWire.hxx>
  30. #include <BRepBuilderAPI_Transform.hxx>
  31. #include <BRepOffsetAPI_MakePipeShell.hxx>
  32. #include <BRep_Tool.hxx>
  33. #include <BRepLib.hxx>
  34. #include <BRepTools.hxx>
  35. #include <BRepLProp_SLProps.hxx>
  36. #include <BRepClass3d_SolidClassifier.hxx>
  37. #include <TopoDS.hxx>
  38. #include <TopoDS_Shape.hxx>
  39. #include <TopoDS_Compound.hxx>
  40. #include <TopoDS_Solid.hxx>
  41. #include <TopoDS_Face.hxx>
  42. #include <TopoDS_Wire.hxx>
  43. #include <TopoDS_Edge.hxx>
  44. #include <TopoDS_Vertex.hxx>
  45. #include <TopAbs.hxx>
  46. #include <TopExp.hxx>
  47. #include <TopTools_ListOfShape.hxx>
  48. #include <TopTools_ListIteratorOfListOfShape.hxx>
  49. #include <TopExp_Explorer.hxx>
  50. #include <GProp_GProps.hxx>
  51. #include <BRepGProp.hxx>
  52. #include <gp_Pnt.hxx>
  53. #include <gp_Lin.hxx>
  54. #include <gp_Dir.hxx>
  55. #include <gp_Ax2.hxx>
  56. #include <Geom_CylindricalSurface.hxx>
  57. #include <Geom_ConicalSurface.hxx>
  58. #include <Geom_Line.hxx>
  59. #include <Geom2d_TrimmedCurve.hxx>
  60. #include <GeomAPI_ProjectPointOnCurve.hxx>
  61. #include <GCE2d_MakeSegment.hxx>
  62. #include <ShHealOper_Sewing.hxx>
  63. #include <ShHealOper_FillHoles.hxx>
  64. #include <BRepAdaptor_Curve.hxx>
  65. #include <Precision.hxx>
  66. #include <StdFail_NotDone.hxx>
  67. #include <Standard_TypeMismatch.hxx>
  68. #include <Standard_ConstructionError.hxx>
  69. gp_Pnt GetVertexOnWireNotOnAxis(TopoDS_Wire aWire/*, Standard_Boolean isFirst*/, gp_Ax1 ax)
  70. {
  71. //find a subvertex of the wire that isn't on ax
  72. Handle_Geom_Line aLine = new Geom_Line(ax);
  73. TopTools_IndexedMapOfShape map;
  74. TopExp::MapShapes( aWire, TopAbs_VERTEX, map );
  75. for( int i=1; i<=map.Extent(); i++ )
  76. {
  77. gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( map.FindKey( i ) ) );
  78. GeomAPI_ProjectPointOnCurve proj(p,aLine);
  79. if( proj.NbPoints() > 0 )
  80. {
  81. if( proj.Distance( 1 ) > Precision::Confusion() )
  82. return p;
  83. }
  84. }
  85. // if we got here, we haven't found a vertex NOT on ax
  86. // search for a value of an edge NOT on ax
  87. const int nSamples=10;
  88. map.Clear();
  89. TopExp::MapShapes( aWire, TopAbs_EDGE, map );
  90. for( int i=1; i<=map.Extent(); i++ )
  91. {
  92. BRepAdaptor_Curve curve(TopoDS::Edge( map.FindKey( i ) ));
  93. Standard_Real umin = curve.FirstParameter();
  94. Standard_Real umax = curve.LastParameter();
  95. for( int n = 0; n <= nSamples; n++ )
  96. {
  97. Standard_Real u = umin + (float(n)/float(nSamples))*( umax - umin );
  98. gp_Pnt p = curve.Value(u);
  99. GeomAPI_ProjectPointOnCurve proj(p,aLine);
  100. if( proj.NbPoints() > 0 )
  101. {
  102. if( proj.Distance( 1 ) > Precision::Confusion() )
  103. return p;
  104. }
  105. }
  106. }
  107. // if we got here, no appropriate point was found, so throw an exception
  108. Standard_ConstructionError::Raise("No point found on wire, that is not on axis");
  109. return gp_Pnt(0., 0., 0.);
  110. }
  111. static TopoDS_Wire getHelicalSpine( gp_Pnt p, gp_Ax1 ax, Standard_Real angle, Standard_Real aConicalAngle, Standard_Real offset )
  112. {
  113. //project the point on the axis
  114. Handle_Geom_Line aLine = new Geom_Line(ax);
  115. GeomAPI_ProjectPointOnCurve proj(p,aLine);
  116. gp_Pnt pOnAx = proj.Point(1);
  117. gp_Vec vec(pOnAx,p);
  118. gp_Ax2 ax2( pOnAx, ax.Direction(), gp_Dir(vec) );
  119. // create the surface
  120. Handle(Geom_ElementarySurface) aSurf;
  121. if (aConicalAngle)
  122. aSurf = new Geom_ConicalSurface ( ax2, aConicalAngle, vec.Magnitude() );
  123. else
  124. aSurf = new Geom_CylindricalSurface ( ax2, vec.Magnitude() );
  125. //create the 2d line on the surface
  126. Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(gp_Pnt2d(0.0,0.0), gp_Pnt2d(angle,offset) );
  127. TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aSegment , aSurf);
  128. TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(anEdge);
  129. BRepLib::BuildCurves3d(aWire);
  130. return aWire;
  131. }
  132. static const TopTools_ListOfShape& getThruSections( TopoDS_Wire w, gp_Ax1 ax, Standard_Real angle, Standard_Real aConicalAngle, Standard_Real offset, int sectionCount )
  133. {
  134. static TopTools_ListOfShape result;
  135. result.Clear();
  136. gp_Trsf tsfTrans;
  137. gp_Trsf tsfRot;
  138. gp_Trsf tsfCone;
  139. gp_Vec anOffsetVec = gp_Vec(ax.Direction());
  140. Handle_Geom_Line anAxisLine = new Geom_Line(ax);
  141. for( int i = 1; i <= sectionCount; i++ )
  142. {
  143. Standard_Real anOffset = offset*double(i)/double(sectionCount);
  144. tsfTrans.SetTranslation( anOffset*anOffsetVec );
  145. BRepBuilderAPI_Transform trsfTrans(tsfTrans);
  146. trsfTrans.Perform(w, Standard_True);
  147. Standard_Real anAngle = angle*double(i)/double(sectionCount);
  148. tsfRot.SetRotation( ax, anAngle );
  149. BRepBuilderAPI_Transform trsfRot(tsfRot);
  150. trsfRot.Perform(trsfTrans, Standard_False);
  151. if (aConicalAngle) {
  152. gp_Pnt theCurrentPnt = GetVertexOnWireNotOnAxis(TopoDS::Wire(trsfRot), ax);
  153. GeomAPI_ProjectPointOnCurve proj(theCurrentPnt,anAxisLine);
  154. gp_Pnt pOnAx = proj.Point(1);
  155. gp_Vec CurrVec(pOnAx,theCurrentPnt);
  156. CurrVec.Normalize();
  157. Standard_Real aConicOffset = anOffset * (Tan(aConicalAngle));
  158. tsfCone.SetTranslation(CurrVec*aConicOffset);
  159. BRepBuilderAPI_Transform trsfCone(tsfCone);
  160. trsfCone.Perform(trsfRot, Standard_False);
  161. result.Append(trsfCone);
  162. }
  163. else
  164. result.Append(trsfRot);
  165. }
  166. return result;
  167. }
  168. //=======================================================================
  169. //function : GetID
  170. //purpose :
  171. //=======================================================================
  172. const Standard_GUID& GEOMImpl_RevolutionDriver::GetID()
  173. {
  174. static Standard_GUID aRevolutionDriver("FF1BBB18-5D14-4df2-980B-3A668264EA16");
  175. return aRevolutionDriver;
  176. }
  177. //=======================================================================
  178. //function : GEOMImpl_RevolutionDriver
  179. //purpose :
  180. //=======================================================================
  181. GEOMImpl_RevolutionDriver::GEOMImpl_RevolutionDriver()
  182. {
  183. }
  184. //=======================================================================
  185. //function : Execute
  186. //purpose :
  187. //=======================================================================
  188. Standard_Integer GEOMImpl_RevolutionDriver::Execute(TFunction_Logbook& log) const
  189. {
  190. if (Label().IsNull()) return 0;
  191. Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
  192. GEOMImpl_IRevolution aCI (aFunction);
  193. Standard_Integer aType = aFunction->GetType();
  194. TopoDS_Shape aShape;
  195. if (aType == REVOLUTION_BASE_AXIS_ANGLE || aType == REVOLUTION_BASE_AXIS_ANGLE_2WAYS) {
  196. Handle(GEOM_Function) aRefBase = aCI.GetBase();
  197. Handle(GEOM_Function) aRefAxis = aCI.GetAxis();
  198. TopoDS_Shape aShapeBase = aRefBase->GetValue();
  199. TopoDS_Shape aShapeAxis = aRefAxis->GetValue();
  200. if (aShapeAxis.ShapeType() != TopAbs_EDGE) {
  201. Standard_TypeMismatch::Raise("Revolution Axis must be an edge");
  202. }
  203. TopoDS_Edge anE = TopoDS::Edge(aShapeAxis);
  204. TopoDS_Vertex V1, V2;
  205. TopExp::Vertices(anE, V1, V2, Standard_True);
  206. if (V1.IsNull() || V2.IsNull()) {
  207. Standard_ConstructionError::Raise("Bad edge for the Revolution Axis given");
  208. }
  209. gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
  210. if (aV.Magnitude() < Precision::Confusion()) {
  211. Standard_ConstructionError::Raise
  212. ("End vertices of edge, defining the Revolution Axis, are too close");
  213. }
  214. if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
  215. gp_Lin aL(BRep_Tool::Pnt(V1), gp_Dir(aV));
  216. Standard_Real d = aL.Distance(BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase)));
  217. if (d < Precision::Confusion()) {
  218. Standard_ConstructionError::Raise("Vertex to be rotated is too close to Revolution Axis");
  219. }
  220. }
  221. double anAngle = aCI.GetAngle();
  222. gp_Ax1 anAxis (BRep_Tool::Pnt(V1), aV);
  223. if (aType == REVOLUTION_BASE_AXIS_ANGLE_2WAYS)
  224. {
  225. gp_Trsf aTrsf;
  226. aTrsf.SetRotation(anAxis, ( -anAngle ));
  227. BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
  228. aShapeBase = aTransformation.Shape();
  229. anAngle = anAngle * 2;
  230. }
  231. BRepPrimAPI_MakeRevol MR (aShapeBase, anAxis, anAngle, Standard_False);
  232. if (!MR.IsDone()) MR.Build();
  233. if (!MR.IsDone()) StdFail_NotDone::Raise("Revolution algorithm has failed");
  234. aShape = MR.Shape();
  235. } else if (aType == REVOLUTION_BASE_AXIS_ANGLE_OFFSET) {
  236. /*
  237. MakeRevolutionAxisAngleOffset creates a shape by revolving a vertex/edge/wire/face(the "profile") around an axis with an offset along the axis.
  238. Depending on the input shape(vertex,edge,wire or face), the result will be an edge,face,shell or solid, in that order.
  239. To keep the order of the result shape low, the function acts per revolution. For each revolution the function creates
  240. - a helix spine beginning at a vertex on the profile, see getHelicalSpine.
  241. - 4 thru sections to delimit the result shape
  242. Then BRepOffsetAPI_MakePipeShell is used to build each an intermediate result for each revolution.
  243. These revolutions are then sewn together to build the result.
  244. */
  245. Handle(GEOM_Function) aRefBase = aCI.GetBase();
  246. Handle(GEOM_Function) aRefAxis = aCI.GetAxis();
  247. TopoDS_Shape aShapeBase = aRefBase->GetValue();
  248. TopoDS_Shape aShapeAxis = aRefAxis->GetValue();
  249. if (aShapeAxis.ShapeType() != TopAbs_EDGE) {
  250. Standard_TypeMismatch::Raise("Revolution Axis must be an edge");
  251. }
  252. TopoDS_Edge anE = TopoDS::Edge(aShapeAxis);
  253. TopoDS_Vertex V1, V2;
  254. TopExp::Vertices(anE, V1, V2, Standard_True);
  255. if (V1.IsNull() || V2.IsNull()) {
  256. Standard_ConstructionError::Raise("Bad edge for the Revolution Axis given");
  257. }
  258. gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
  259. if (aV.Magnitude() < Precision::Confusion()) {
  260. Standard_ConstructionError::Raise
  261. ("End vertices of edge, defining the Revolution Axis, are too close");
  262. }
  263. if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
  264. gp_Lin aL(BRep_Tool::Pnt(V1), gp_Dir(aV));
  265. Standard_Real d = aL.Distance(BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase)));
  266. if (d < Precision::Confusion()) {
  267. Standard_ConstructionError::Raise("Vertex to be rotated is too close to Revolution Axis");
  268. }
  269. }
  270. gp_Ax1 anAxis (BRep_Tool::Pnt(V1), aV);
  271. //values from driver
  272. Standard_Real theTotalAngleInRAD = aCI.GetAngle();
  273. Standard_Real theTotalOffset = aCI.GetOffset();
  274. Standard_Real theConeAngle = aCI.GetConeAngle();
  275. //constants used below
  276. Standard_Real theRevolutionResolution = (PI/2);
  277. Standard_Integer theNbWiresPerRevolution = 4;
  278. //create the basic wire or vertex
  279. TopAbs_ShapeEnum aTypeBase = aShapeBase.ShapeType();
  280. Standard_Boolean NeedCreateSolid = Standard_False;
  281. Standard_Boolean IsVertex = Standard_False;
  282. TopoDS_Wire aWireProf;
  283. TopoDS_Vertex myVertex;
  284. if(aTypeBase == TopAbs_WIRE) {
  285. aWireProf = TopoDS::Wire(aShapeBase);
  286. }
  287. else if(aTypeBase == TopAbs_FACE) {
  288. NeedCreateSolid = Standard_True;
  289. aWireProf = BRepTools::OuterWire(TopoDS::Face(aShapeBase));
  290. }
  291. else if(aTypeBase == TopAbs_EDGE){
  292. TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
  293. aWireProf = BRepBuilderAPI_MakeWire(anEdge);
  294. }
  295. else if(aTypeBase == TopAbs_VERTEX){
  296. IsVertex = Standard_True;
  297. myVertex = TopoDS::Vertex(aShapeBase);
  298. }
  299. else
  300. Standard_ConstructionError::Raise("Construction element is not of the requested type");
  301. if (!IsVertex)
  302. {
  303. gp_Pnt theCurrentPnt = GetVertexOnWireNotOnAxis(aWireProf, anAxis);
  304. TopoDS_Wire theCurrentWire = aWireProf;
  305. Standard_Real theCurrAngle = theTotalAngleInRAD;
  306. Standard_Boolean isFinished = Standard_False;
  307. TopTools_ListOfShape listForCompound;
  308. while (!isFinished)
  309. {
  310. if (theCurrAngle > theRevolutionResolution)
  311. theCurrAngle = theCurrAngle-theRevolutionResolution;
  312. else
  313. {
  314. theRevolutionResolution = theCurrAngle;
  315. isFinished = Standard_True;
  316. }
  317. Standard_Real theOffset = (theTotalOffset /theTotalAngleInRAD ) * theRevolutionResolution;
  318. TopoDS_Wire aSpine = getHelicalSpine( theCurrentPnt, anAxis, theRevolutionResolution, theConeAngle, theOffset );
  319. TopoDS_Vertex aFirst, aLast;
  320. TopExp::Vertices(aSpine, aFirst, aLast);
  321. theCurrentPnt = BRep_Tool::Pnt(aLast);
  322. const TopTools_ListOfShape& listThru = getThruSections( theCurrentWire, anAxis, theRevolutionResolution, theConeAngle, theOffset, theNbWiresPerRevolution );
  323. theCurrentWire = TopoDS::Wire(listThru.Last());
  324. BRepOffsetAPI_MakePipeShell mps(aSpine);
  325. TopTools_ListIteratorOfListOfShape it;
  326. for( it.Initialize( listThru ); it.More(); it.Next() )
  327. mps.Add( it.Value() );
  328. listForCompound.Append(mps.Shape());
  329. }
  330. TopoDS_Compound CompoundNotSewed;
  331. BRep_Builder CompoundBuilder;
  332. CompoundBuilder.MakeCompound(CompoundNotSewed);
  333. TopTools_ListIteratorOfListOfShape it;
  334. for( it.Initialize( listForCompound ); it.More(); it.Next() )
  335. CompoundBuilder.Add(CompoundNotSewed, it.Value());
  336. if (NeedCreateSolid) {
  337. CompoundBuilder.Add (CompoundNotSewed, aShapeBase );
  338. gp_Trsf tsfTrans;
  339. gp_Trsf tsfRot;
  340. gp_Trsf tsfCone;
  341. gp_Vec anOffsetVec = gp_Vec(anAxis.Direction());
  342. tsfTrans.SetTranslation( theTotalOffset*anOffsetVec );
  343. BRepBuilderAPI_Transform trsfTrans(tsfTrans);
  344. trsfTrans.Perform(aShapeBase, Standard_True);
  345. tsfRot.SetRotation( anAxis, theTotalAngleInRAD );
  346. BRepBuilderAPI_Transform trsfRot(tsfRot);
  347. trsfRot.Perform(trsfTrans, Standard_False);
  348. if (theConeAngle) {
  349. Handle_Geom_Line anAxisLine = new Geom_Line(anAxis);
  350. Standard_Real aConicOffset = theTotalOffset * (Tan(theConeAngle));
  351. gp_Pnt theCurrentPnt = GetVertexOnWireNotOnAxis(BRepTools::OuterWire(TopoDS::Face(trsfRot)), anAxis);
  352. GeomAPI_ProjectPointOnCurve proj(theCurrentPnt,anAxisLine);
  353. gp_Pnt pOnAx = proj.Point(1);
  354. gp_Vec CurrVec(pOnAx,theCurrentPnt);
  355. CurrVec.Normalize();
  356. tsfCone.SetTranslation(CurrVec*aConicOffset);
  357. BRepBuilderAPI_Transform trsfCone(tsfCone);
  358. trsfCone.Perform(trsfRot, Standard_False);
  359. CompoundBuilder.Add(CompoundNotSewed, trsfCone );
  360. }
  361. else
  362. CompoundBuilder.Add(CompoundNotSewed, trsfRot );
  363. }
  364. Standard_Real DefaultSewTolerance = 10.;
  365. ShHealOper_Sewing aHealer (CompoundNotSewed, DefaultSewTolerance);
  366. TopoDS_Shape CompoundSewed;
  367. if (aHealer.Perform())
  368. CompoundSewed = aHealer.GetResultShape();
  369. else
  370. CompoundSewed = CompoundNotSewed;
  371. if (NeedCreateSolid) {
  372. TopoDS_Solid aSolid;
  373. BRep_Builder aSolidBuilder;
  374. aSolidBuilder.MakeSolid(aSolid);
  375. TopExp_Explorer aExpW(CompoundSewed, TopAbs_SHELL );
  376. for( ; aExpW.More(); aExpW.Next())
  377. aSolidBuilder.Add(aSolid, aExpW.Current());
  378. BRepClass3d_SolidClassifier SC(aSolid);
  379. SC.PerformInfinitePoint(Precision::Confusion());
  380. switch (SC.State()) {
  381. case TopAbs_IN:
  382. aShape = aSolid.Reversed();
  383. break;
  384. case TopAbs_OUT:
  385. aShape = aSolid;
  386. break;
  387. default:
  388. aShape = CompoundSewed;
  389. }
  390. }
  391. else {
  392. aShape = CompoundSewed;
  393. }
  394. }
  395. else
  396. {
  397. gp_Pnt theCurrentPnt = BRep_Tool::Pnt(myVertex);
  398. aShape = getHelicalSpine( theCurrentPnt, anAxis, theTotalAngleInRAD, theConeAngle, theTotalOffset );
  399. }
  400. } else {
  401. }
  402. if (aShape.IsNull()) return 0;
  403. TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape);
  404. aFunction->SetValue(aRes);
  405. log.SetTouched(Label());
  406. return 1;
  407. }
  408. //=======================================================================
  409. //function : GEOMImpl_RevolutionDriver_Type_
  410. //purpose :
  411. //=======================================================================
  412. Standard_EXPORT Handle_Standard_Type& GEOMImpl_RevolutionDriver_Type_()
  413. {
  414. static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
  415. if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
  416. static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
  417. if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
  418. static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
  419. if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
  420. static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
  421. static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_RevolutionDriver",
  422. sizeof(GEOMImpl_RevolutionDriver),
  423. 1,
  424. (Standard_Address)_Ancestors,
  425. (Standard_Address)NULL);
  426. return _aType;
  427. }
  428. //=======================================================================
  429. //function : DownCast
  430. //purpose :
  431. //=======================================================================
  432. const Handle(GEOMImpl_RevolutionDriver) Handle(GEOMImpl_RevolutionDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
  433. {
  434. Handle(GEOMImpl_RevolutionDriver) _anOtherObject;
  435. if (!AnObject.IsNull()) {
  436. if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_RevolutionDriver))) {
  437. _anOtherObject = Handle(GEOMImpl_RevolutionDriver)((Handle(GEOMImpl_RevolutionDriver)&)AnObject);
  438. }
  439. }
  440. return _anOtherObject ;
  441. }