PageRenderTime 64ms CodeModel.GetById 21ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 0ms

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