Back to index

salome-geom  6.5.0
ShHealOper_EdgeDivide.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:      ShHealOper_EdgeDivide.cxx
00024 // Created:   30.04.04 16:44:47
00025 // Author:    Galina KULIKOVA
00026 //
00027 #include <ShHealOper_EdgeDivide.hxx>
00028 #include <ShapeUpgrade_WireDivide.hxx>
00029 #include <ShHealOper_SplitCurve3d.hxx>
00030 #include <ShHealOper_SplitCurve2d.hxx>
00031 #include <TopTools_ListOfShape.hxx>
00032 #include <TopTools_ListIteratorOfListOfShape.hxx>
00033 #include <BRep_Tool.hxx>
00034 #include <ShapeFix_Edge.hxx>
00035 #include <ShapeAnalysis_Edge.hxx>
00036 #include <GeomAdaptor_Curve.hxx>
00037 #include <Geom2dAdaptor_Curve.hxx>
00038 #include <TopoDS.hxx>
00039 #include <Geom_Curve.hxx>
00040 #include <TopoDS_Face.hxx>
00041 #include <Geom2d_Curve.hxx>
00042 #include <GCPnts_AbscissaPoint.hxx>
00043 #include <TopExp.hxx>
00044 #include <Precision.hxx>
00045 //#include <.hxx>
00046 //#include <.hxx>
00047 //=======================================================================
00048 //function : ShHealOper_EdgeDivide()
00049 //purpose  : Constructor
00050 //=======================================================================
00051 
00052 ShHealOper_EdgeDivide::ShHealOper_EdgeDivide (const TopoDS_Shape& theShape) 
00053 {
00054   Init(theShape);
00055 }
00056 //=======================================================================
00057 //function : Init
00058 //purpose  : 
00059 //=======================================================================
00060 
00061 void ShHealOper_EdgeDivide::Init(const TopoDS_Shape& theShape)
00062 {
00063   ShHealOper_Tool::Init(theShape);
00064   myDivideParamMode = Standard_True;
00065   myMapEdgesFace.Clear();
00066   TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,myMapEdgesFace);
00067   
00068 }
00069 
00070 //=======================================================================
00071 //function : Perform
00072 //purpose  : 
00073 //=======================================================================
00074 Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge, 
00075                                                 const TColStd_SequenceOfReal& theValues,
00076                                                 const Standard_Boolean theDivideParamMode)
00077 { 
00078   myDone = Standard_False;
00079   myDivideParamMode = theDivideParamMode;
00080   if(theEdge.ShapeType() != TopAbs_EDGE) {
00081     myErrorStatus = ShHealOper_InvalidParameters;
00082     return myDone;
00083   }
00084   myEdge = TopoDS::Edge(theEdge);
00085   Standard_Integer i =1;
00086   Handle(TColStd_HSequenceOfReal) aSeqValues = new TColStd_HSequenceOfReal;
00087   for( ; i <= theValues.Length(); i++)
00088       aSeqValues->Append(theValues.Value(i));
00089   myDone = build(aSeqValues);
00090   return myDone;
00091   
00092 }
00093 //=======================================================================
00094 //function : Perform
00095 //purpose  : 
00096 //=======================================================================
00097 
00098 Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge, 
00099                                                 const Standard_Real theValue,
00100                                                 const Standard_Boolean theDivideParamMode)
00101 {
00102   myDone = Standard_False;
00103   myErrorStatus = ShHealOper_NotError;
00104   if(theEdge.ShapeType() != TopAbs_EDGE) {
00105     myErrorStatus = ShHealOper_InvalidParameters;
00106     return myDone;
00107   }
00108   myDivideParamMode = theDivideParamMode;
00109   myEdge = TopoDS::Edge(theEdge);
00110   Handle(TColStd_HSequenceOfReal) aSeqValues = new TColStd_HSequenceOfReal;
00111   aSeqValues->Append(theValue);
00112   myDone = build(aSeqValues);
00113   return myDone;
00114 }
00115 //=======================================================================
00116 //function : build
00117 //purpose  : 
00118 //=======================================================================
00119 
00120 Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfReal)& theValues)
00121 {
00122   if(myEdge.IsNull() || !theValues->Length()) {
00123     myErrorStatus = ShHealOper_InvalidParameters;
00124     return Standard_False;
00125   }
00126 
00127   Standard_Boolean has3d = Standard_False, 
00128   has2d = Standard_False, 
00129   hasPCurves = Standard_False;
00130   
00131   //computation of the split values in dependance from specified mode and values.
00132   if(!computeValues(theValues, has3d,has2d,hasPCurves)) {
00133     myErrorStatus = ShHealOper_InvalidParameters;
00134     return Standard_False;
00135   }
00136   
00137   //setting split values in the splitting curve tools.
00138   Handle(ShapeUpgrade_WireDivide) aSplitTool = new ShapeUpgrade_WireDivide;
00139   aSplitTool->Load(myEdge);
00140   aSplitTool->SetContext(myContext);
00141   if(has3d) {
00142     Handle(ShHealOper_SplitCurve3d) aSplitCurve3d = new ShHealOper_SplitCurve3d;
00143     aSplitCurve3d->SetValues(theValues);
00144     aSplitTool->SetSplitCurve3dTool(aSplitCurve3d);
00145   }
00146   else if(has2d) {
00147     Handle(ShHealOper_SplitCurve2d) aSplitCurve2d = new ShHealOper_SplitCurve2d;
00148     aSplitCurve2d->SetValues(theValues);
00149     aSplitTool->SetSplitCurve2dTool(aSplitCurve2d);
00150   }
00151   else {
00152     myErrorStatus = ShHealOper_InvalidParameters;
00153     return Standard_False;
00154   }
00155   
00156   //split 3d curve and pcurve for each face reffering to edge.
00157   Standard_Boolean isDone = Standard_True;
00158   if(hasPCurves) {
00159     const TopTools_ListOfShape& lfaces  = myMapEdgesFace.FindFromKey(myEdge);
00160     TopTools_ListIteratorOfListOfShape aItf(lfaces);
00161     for( ; aItf.More() && isDone; aItf.Next()) {
00162       TopoDS_Face aFace = TopoDS::Face(aItf.Value());
00163       aSplitTool->SetFace(aFace);
00164       aSplitTool->Perform();
00165       isDone = aSplitTool->Status( ShapeExtend_DONE );
00166       if( aSplitTool->Status( ShapeExtend_FAIL ))
00167         myErrorStatus = ShHealOper_ErrorExecution;
00168     }
00169   }
00170   else {
00171      aSplitTool->Perform();
00172      isDone = aSplitTool->Status( ShapeExtend_DONE );
00173      if( aSplitTool->Status( ShapeExtend_FAIL ))
00174         myErrorStatus = ShHealOper_ErrorExecution;
00175   }
00176   if(isDone)
00177     myResultShape = myContext->Apply(myInitShape);
00178   return isDone;
00179   
00180 }
00181 //=======================================================================
00182 //function : computeValues
00183 //purpose  : 
00184 //=======================================================================
00185 
00186 Standard_Boolean ShHealOper_EdgeDivide::computeValues(const Handle(TColStd_HSequenceOfReal)& theValues,
00187                                                       Standard_Boolean& theHas3d,
00188                                                       Standard_Boolean& theHas2d,
00189                                                       Standard_Boolean& hasPCurves)
00190 {
00191   hasPCurves = (myMapEdgesFace.Contains(myEdge) && 
00192                 myMapEdgesFace.FindFromKey(myEdge).Extent());
00193   if(hasPCurves && (!BRep_Tool::SameRange(myEdge) || !BRep_Tool::SameParameter(myEdge))) {
00194     ShapeFix_Edge sfe;
00195     sfe.FixSameParameter(myEdge);
00196   }
00197   
00198   Standard_Real aFirst =0.,aLast=0.;
00199 
00200   //computation of the split values if edge should be splitted by parameter.
00201   if(myDivideParamMode) {
00202     BRep_Tool::Range(myEdge,aFirst,aLast);
00203     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge,aFirst,aLast);
00204     
00205     theHas3d = (!aCurve.IsNull());
00206     theHas2d = (aCurve.IsNull() && (fabs(aLast-aFirst) > Precision::PConfusion() ));
00207     Standard_Integer i = 1;
00208     for( ; i <= theValues->Length();i++) {
00209       Standard_Real aVal = theValues->Value(i);
00210       theValues->ChangeValue(i) = aFirst+ aVal*fabs(aLast - aFirst);
00211     }
00212   }
00213   else {
00214      //computation of the split values if edge should be splitted by length.
00215     ShapeAnalysis_Edge sae;
00216     Handle(Geom_Curve) aCurve;
00217     Standard_Real aCurLen =0.;
00218     GeomAdaptor_Curve aAdC;
00219     Geom2dAdaptor_Curve aAdC2d;
00220     if(sae.Curve3d(myEdge,aCurve,aFirst,aLast,Standard_False)) {
00221       aAdC.Load(aCurve,aFirst,aLast);
00222       aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast); 
00223       theHas3d = Standard_True;
00224     }
00225     else {
00226       if(hasPCurves) {
00227         TopoDS_Face aFace = TopoDS::Face(myMapEdgesFace.FindFromKey(myEdge).First());
00228         Handle(Geom2d_Curve) aCurve2d;
00229         if(sae.PCurve(myEdge,aFace,aCurve2d,aFirst,aLast)) {
00230           aAdC2d.Load(aCurve2d,aFirst,aLast);
00231           aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast);
00232           theHas2d = Standard_True;
00233         }
00234           
00235       }
00236     }
00237     if(!theHas3d && !theHas2d)
00238       return Standard_False;
00239 
00240     Standard_Integer i = 1;
00241     for( ; i <= theValues->Length();i++) {
00242       Standard_Real aLen = theValues->Value(i)*aCurLen;
00243       if(theHas3d) {
00244         GCPnts_AbscissaPoint anAbsc(aAdC,aLen,aFirst);
00245         if(anAbsc.IsDone()) 
00246           theValues->ChangeValue(i) = anAbsc.Parameter();
00247         else
00248           theValues->Remove(i--);
00249       }
00250       else if(theHas2d) {
00251         GCPnts_AbscissaPoint anAbsc(aAdC2d,aLen,aFirst);
00252         if(anAbsc.IsDone()) 
00253           theValues->ChangeValue(i) = anAbsc.Parameter();
00254         else
00255           theValues->Remove(i--);
00256       }
00257     }
00258   }
00259   return (theValues->Length());
00260 }