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

http://pythonocc.googlecode.com/ · C++ · 291 lines · 201 code · 38 blank · 52 comment · 52 complexity · 4f5c0a3ab529741cdbeede6924309259 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_ScaleDriver.hxx>
  23. #include <GEOMImpl_IScale.hxx>
  24. #include <GEOMImpl_Types.hxx>
  25. #include <GEOM_Function.hxx>
  26. #include <GEOM_Object.hxx>
  27. #include <ShapeFix_Shape.hxx>
  28. #include <ShapeFix_ShapeTolerance.hxx>
  29. #include <BRepBuilderAPI_Transform.hxx>
  30. #include <BRepBuilderAPI_GTransform.hxx>
  31. #include <BRep_Tool.hxx>
  32. #include <BRepAlgo.hxx>
  33. #include <TopAbs.hxx>
  34. #include <TopExp.hxx>
  35. #include <TopoDS.hxx>
  36. #include <TopoDS_Shape.hxx>
  37. #include <TopoDS_Vertex.hxx>
  38. #include <TopoDS_Edge.hxx>
  39. #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
  40. #include <BRepCheck_Analyzer.hxx>
  41. #include <Precision.hxx>
  42. #include <gp_Pnt.hxx>
  43. #include <gp_Ax1.hxx>
  44. #include <gp_GTrsf.hxx>
  45. //=======================================================================
  46. //function : GetID
  47. //purpose :
  48. //=======================================================================
  49. const Standard_GUID& GEOMImpl_ScaleDriver::GetID()
  50. {
  51. static Standard_GUID aScaleDriver("FF1BBB52-5D14-4df2-980B-3A668264EA16");
  52. return aScaleDriver;
  53. }
  54. //=======================================================================
  55. //function : GEOMImpl_ScaleDriver
  56. //purpose :
  57. //=======================================================================
  58. GEOMImpl_ScaleDriver::GEOMImpl_ScaleDriver()
  59. {
  60. }
  61. //=======================================================================
  62. //function : Execute
  63. //purpose :
  64. //=======================================================================
  65. Standard_Integer GEOMImpl_ScaleDriver::Execute(TFunction_Logbook& log) const
  66. {
  67. if (Label().IsNull()) return 0;
  68. Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
  69. GEOMImpl_IScale aCI (aFunction);
  70. Standard_Integer aType = aFunction->GetType();
  71. TopoDS_Shape aShape;
  72. if (aType == SCALE_SHAPE || aType == SCALE_SHAPE_COPY) {
  73. Handle(GEOM_Function) aRefShape = aCI.GetShape();
  74. TopoDS_Shape aShapeBase = aRefShape->GetValue();
  75. if (aShapeBase.IsNull()) return 0;
  76. gp_Pnt aP (0,0,0);
  77. Handle(GEOM_Function) aRefPoint = aCI.GetPoint();
  78. if (!aRefPoint.IsNull()) {
  79. TopoDS_Shape aShapePnt = aRefPoint->GetValue();
  80. if (aShapePnt.IsNull()) return 0;
  81. if (aShapePnt.ShapeType() != TopAbs_VERTEX) return 0;
  82. aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
  83. }
  84. // Bug 6839: Check for standalone (not included in faces) degenerated edges
  85. TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
  86. TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
  87. Standard_Integer i, nbE = aEFMap.Extent();
  88. for (i = 1; i <= nbE; i++) {
  89. TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
  90. if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
  91. const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
  92. if (aFaces.IsEmpty())
  93. Standard_ConstructionError::Raise
  94. ("Scaling aborted : cannot scale standalone degenerated edge");
  95. }
  96. }
  97. // Perform Scaling
  98. gp_Trsf aTrsf;
  99. aTrsf.SetScale(aP, aCI.GetFactor());
  100. BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
  101. aShape = aBRepTrsf.Shape();
  102. }
  103. else if (aType == SCALE_SHAPE_AFFINE || aType == SCALE_SHAPE_AFFINE_COPY) {
  104. Handle(GEOM_Function) aRefShape = aCI.GetShape();
  105. Handle(GEOM_Function) aRefVector = aCI.GetVector();
  106. TopoDS_Shape aShapeBase = aRefShape->GetValue();
  107. TopoDS_Shape aShapeVector = aRefVector->GetValue();
  108. if (aShapeBase.IsNull() || aShapeVector.IsNull()) return 0;
  109. if (aShapeVector.ShapeType() != TopAbs_EDGE) return 0;
  110. TopoDS_Edge anEdgeVector = TopoDS::Edge(aShapeVector);
  111. // Bug 6839: Check for standalone (not included in faces) degenerated edges
  112. TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
  113. TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
  114. Standard_Integer i, nbE = aEFMap.Extent();
  115. for (i = 1; i <= nbE; i++) {
  116. TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
  117. if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
  118. const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
  119. if (aFaces.IsEmpty())
  120. Standard_ConstructionError::Raise
  121. ("Scaling aborted : cannot scale standalone degenerated edge");
  122. }
  123. }
  124. //Get axis
  125. gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdgeVector));
  126. gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdgeVector));
  127. gp_Dir aDir(gp_Vec(aP1, aP2));
  128. gp_Ax2 anAx2(aP1, aDir);
  129. // Perform Scaling
  130. gp_GTrsf aGTrsf;
  131. aGTrsf.SetAffinity(anAx2, aCI.GetFactor());
  132. BRepBuilderAPI_GTransform aBRepGTrsf(aShapeBase, aGTrsf, Standard_False);
  133. aShape = aBRepGTrsf.Shape();
  134. }
  135. else if (aType == SCALE_SHAPE_AXES || aType == SCALE_SHAPE_AXES_COPY) {
  136. Handle(GEOM_Function) aRefShape = aCI.GetShape();
  137. TopoDS_Shape aShapeBase = aRefShape->GetValue();
  138. if (aShapeBase.IsNull()) return 0;
  139. bool isP = false;
  140. gp_Pnt aP (0,0,0);
  141. Handle(GEOM_Function) aRefPoint = aCI.GetPoint();
  142. if (!aRefPoint.IsNull()) {
  143. TopoDS_Shape aShapePnt = aRefPoint->GetValue();
  144. if (aShapePnt.IsNull()) return 0;
  145. if (aShapePnt.ShapeType() != TopAbs_VERTEX) return 0;
  146. aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
  147. isP = true;
  148. }
  149. // Bug 6839: Check for standalone (not included in faces) degenerated edges
  150. TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
  151. TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
  152. Standard_Integer i, nbE = aEFMap.Extent();
  153. for (i = 1; i <= nbE; i++) {
  154. TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
  155. if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
  156. const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
  157. if (aFaces.IsEmpty())
  158. Standard_ConstructionError::Raise
  159. ("Scaling aborted : cannot scale standalone degenerated edge");
  160. }
  161. }
  162. // Perform Scaling
  163. gp_GTrsf aGTrsf;
  164. gp_Mat rot (aCI.GetFactorX(), 0, 0,
  165. 0, aCI.GetFactorY(), 0,
  166. 0, 0, aCI.GetFactorZ());
  167. aGTrsf.SetVectorialPart(rot);
  168. if (isP) {
  169. gp_Pnt anO (0,0,0);
  170. if (anO.Distance(aP) > Precision::Confusion()) {
  171. gp_GTrsf aGTrsfP0;
  172. aGTrsfP0.SetTranslationPart(anO.XYZ() - aP.XYZ());
  173. gp_GTrsf aGTrsf0P;
  174. aGTrsf0P.SetTranslationPart(aP.XYZ());
  175. //aGTrsf = aGTrsf0P * aGTrsf * aGTrsfP0;
  176. aGTrsf = aGTrsf0P.Multiplied(aGTrsf);
  177. aGTrsf = aGTrsf.Multiplied(aGTrsfP0);
  178. }
  179. }
  180. BRepBuilderAPI_GTransform aBRepGTrsf (aShapeBase, aGTrsf, Standard_False);
  181. if (!aBRepGTrsf.IsDone())
  182. Standard_ConstructionError::Raise("Scaling not done");
  183. aShape = aBRepGTrsf.Shape();
  184. } else {
  185. }
  186. if (aShape.IsNull()) return 0;
  187. // Check shape validity
  188. BRepCheck_Analyzer ana (aShape, false);
  189. if (!ana.IsValid()) {
  190. ShapeFix_ShapeTolerance aSFT;
  191. aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
  192. Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
  193. aSfs->SetPrecision(Precision::Confusion());
  194. aSfs->Perform();
  195. aShape = aSfs->Shape();
  196. ana.Init(aShape, Standard_False);
  197. if (!ana.IsValid()) {
  198. Standard_CString anErrStr("Scaling aborted : non valid shape result");
  199. #ifdef THROW_ON_INVALID_SH
  200. Standard_ConstructionError::Raise(anErrStr);
  201. #else
  202. MESSAGE(anErrStr);
  203. //further processing can be performed here
  204. //...
  205. //in case of failure of automatic treatment
  206. //mark the corresponding GEOM_Object as problematic
  207. TDF_Label aLabel = aFunction->GetOwnerEntry();
  208. if (!aLabel.IsRoot()) {
  209. Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
  210. if (!aMainObj.IsNull())
  211. aMainObj->SetDirty(Standard_True);
  212. }
  213. #endif
  214. }
  215. }
  216. aFunction->SetValue(aShape);
  217. log.SetTouched(Label());
  218. return 1;
  219. }
  220. //=======================================================================
  221. //function : GEOMImpl_ScaleDriver_Type_
  222. //purpose :
  223. //=======================================================================
  224. Standard_EXPORT Handle_Standard_Type& GEOMImpl_ScaleDriver_Type_()
  225. {
  226. static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
  227. if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
  228. static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
  229. if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
  230. static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
  231. if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
  232. static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
  233. static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_ScaleDriver",
  234. sizeof(GEOMImpl_ScaleDriver),
  235. 1,
  236. (Standard_Address)_Ancestors,
  237. (Standard_Address)NULL);
  238. return _aType;
  239. }
  240. //=======================================================================
  241. //function : DownCast
  242. //purpose :
  243. //=======================================================================
  244. const Handle(GEOMImpl_ScaleDriver) Handle(GEOMImpl_ScaleDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
  245. {
  246. Handle(GEOMImpl_ScaleDriver) _anOtherObject;
  247. if (!AnObject.IsNull()) {
  248. if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_ScaleDriver))) {
  249. _anOtherObject = Handle(GEOMImpl_ScaleDriver)((Handle(GEOMImpl_ScaleDriver)&)AnObject);
  250. }
  251. }
  252. return _anOtherObject ;
  253. }