1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, 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.
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
22 // File: ShHealOper_EdgeDivide.cxx
23 // Created: 30.04.04 16:44:47
24 // Author: Galina KULIKOVA
26 #include <ShHealOper_EdgeDivide.hxx>
27 #include <ShapeUpgrade_WireDivide.hxx>
28 #include <ShHealOper_SplitCurve3d.hxx>
29 #include <ShHealOper_SplitCurve2d.hxx>
30 #include <TopTools_ListOfShape.hxx>
31 #include <TopTools_ListIteratorOfListOfShape.hxx>
32 #include <BRep_Tool.hxx>
33 #include <ShapeFix_Edge.hxx>
34 #include <ShapeAnalysis_Edge.hxx>
35 #include <GeomAdaptor_Curve.hxx>
36 #include <Geom2dAdaptor_Curve.hxx>
38 #include <Geom_Curve.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <Geom2d_Curve.hxx>
41 #include <GCPnts_AbscissaPoint.hxx>
43 #include <Precision.hxx>
46 //=======================================================================
47 //function : ShHealOper_EdgeDivide()
48 //purpose : Constructor
49 //=======================================================================
51 ShHealOper_EdgeDivide::ShHealOper_EdgeDivide (const TopoDS_Shape& theShape)
55 //=======================================================================
58 //=======================================================================
60 void ShHealOper_EdgeDivide::Init(const TopoDS_Shape& theShape)
62 ShHealOper_Tool::Init(theShape);
63 myDivideParamMode = Standard_True;
64 myMapEdgesFace.Clear();
65 TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,myMapEdgesFace);
69 //=======================================================================
72 //=======================================================================
73 Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge,
74 const TColStd_SequenceOfReal& theValues,
75 const Standard_Boolean theDivideParamMode)
77 myDone = Standard_False;
78 myDivideParamMode = theDivideParamMode;
79 if(theEdge.ShapeType() != TopAbs_EDGE) {
80 myErrorStatus = ShHealOper_InvalidParameters;
83 myEdge = TopoDS::Edge(theEdge);
84 Standard_Integer i =1;
85 Handle(TColStd_HSequenceOfReal) aSeqValues = new TColStd_HSequenceOfReal;
86 for( ; i <= theValues.Length(); i++)
87 aSeqValues->Append(theValues.Value(i));
88 myDone = build(aSeqValues);
92 //=======================================================================
95 //=======================================================================
97 Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge,
98 const Standard_Real theValue,
99 const Standard_Boolean theDivideParamMode)
101 myDone = Standard_False;
102 myErrorStatus = ShHealOper_NotError;
103 if(theEdge.ShapeType() != TopAbs_EDGE) {
104 myErrorStatus = ShHealOper_InvalidParameters;
107 myDivideParamMode = theDivideParamMode;
108 myEdge = TopoDS::Edge(theEdge);
109 Handle(TColStd_HSequenceOfReal) aSeqValues = new TColStd_HSequenceOfReal;
110 aSeqValues->Append(theValue);
111 myDone = build(aSeqValues);
114 //=======================================================================
117 //=======================================================================
119 Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfReal)& theValues)
121 if(myEdge.IsNull() || !theValues->Length()) {
122 myErrorStatus = ShHealOper_InvalidParameters;
123 return Standard_False;
126 Standard_Boolean has3d = Standard_False,
127 has2d = Standard_False,
128 hasPCurves = Standard_False;
130 //computation of the split values in dependance from specified mode and values.
131 if(!computeValues(theValues, has3d,has2d,hasPCurves)) {
132 myErrorStatus = ShHealOper_InvalidParameters;
133 return Standard_False;
136 //setting split values in the splitting curve tools.
137 Handle(ShapeUpgrade_WireDivide) aSplitTool = new ShapeUpgrade_WireDivide;
138 aSplitTool->Load(myEdge);
139 aSplitTool->SetContext(myContext);
141 Handle(ShHealOper_SplitCurve3d) aSplitCurve3d = new ShHealOper_SplitCurve3d;
142 aSplitCurve3d->SetValues(theValues);
143 aSplitTool->SetSplitCurve3dTool(aSplitCurve3d);
146 Handle(ShHealOper_SplitCurve2d) aSplitCurve2d = new ShHealOper_SplitCurve2d;
147 aSplitCurve2d->SetValues(theValues);
148 aSplitTool->SetSplitCurve2dTool(aSplitCurve2d);
151 myErrorStatus = ShHealOper_InvalidParameters;
152 return Standard_False;
155 //split 3d curve and pcurve for each face reffering to edge.
156 Standard_Boolean isDone = Standard_True;
158 const TopTools_ListOfShape& lfaces = myMapEdgesFace.FindFromKey(myEdge);
159 TopTools_ListIteratorOfListOfShape aItf(lfaces);
160 for( ; aItf.More() && isDone; aItf.Next()) {
161 TopoDS_Face aFace = TopoDS::Face(aItf.Value());
162 aSplitTool->SetFace(aFace);
163 aSplitTool->Perform();
164 isDone = aSplitTool->Status( ShapeExtend_DONE );
165 if( aSplitTool->Status( ShapeExtend_FAIL ))
166 myErrorStatus = ShHealOper_ErrorExecution;
170 aSplitTool->Perform();
171 isDone = aSplitTool->Status( ShapeExtend_DONE );
172 if( aSplitTool->Status( ShapeExtend_FAIL ))
173 myErrorStatus = ShHealOper_ErrorExecution;
176 myResultShape = myContext->Apply(myInitShape);
180 //=======================================================================
181 //function : computeValues
183 //=======================================================================
185 Standard_Boolean ShHealOper_EdgeDivide::computeValues(const Handle(TColStd_HSequenceOfReal)& theValues,
186 Standard_Boolean& theHas3d,
187 Standard_Boolean& theHas2d,
188 Standard_Boolean& hasPCurves)
190 hasPCurves = (myMapEdgesFace.Contains(myEdge) &&
191 myMapEdgesFace.FindFromKey(myEdge).Extent());
192 if(hasPCurves && (!BRep_Tool::SameRange(myEdge) || !BRep_Tool::SameParameter(myEdge))) {
194 sfe.FixSameParameter(myEdge);
197 Standard_Real aFirst =0.,aLast=0.;
199 //computation of the split values if edge should be splitted by parameter.
200 if(myDivideParamMode) {
201 BRep_Tool::Range(myEdge,aFirst,aLast);
202 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge,aFirst,aLast);
204 theHas3d = (!aCurve.IsNull());
205 theHas2d = (aCurve.IsNull() && (fabs(aLast-aFirst) > Precision::PConfusion() ));
206 Standard_Integer i = 1;
207 for( ; i <= theValues->Length();i++) {
208 Standard_Real aVal = theValues->Value(i);
209 theValues->ChangeValue(i) = aFirst+ aVal*fabs(aLast - aFirst);
213 //computation of the split values if edge should be splitted by length.
214 ShapeAnalysis_Edge sae;
215 Handle(Geom_Curve) aCurve;
216 Standard_Real aCurLen =0.;
217 GeomAdaptor_Curve aAdC;
218 Geom2dAdaptor_Curve aAdC2d;
219 if(sae.Curve3d(myEdge,aCurve,aFirst,aLast,Standard_False)) {
220 aAdC.Load(aCurve,aFirst,aLast);
221 aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast);
222 theHas3d = Standard_True;
226 TopoDS_Face aFace = TopoDS::Face(myMapEdgesFace.FindFromKey(myEdge).First());
227 Handle(Geom2d_Curve) aCurve2d;
228 if(sae.PCurve(myEdge,aFace,aCurve2d,aFirst,aLast)) {
229 aAdC2d.Load(aCurve2d,aFirst,aLast);
230 aCurLen = GCPnts_AbscissaPoint::Length(aAdC,aFirst,aLast);
231 theHas2d = Standard_True;
236 if(!theHas3d && !theHas2d)
237 return Standard_False;
239 Standard_Integer i = 1;
240 for( ; i <= theValues->Length();i++) {
241 Standard_Real aLen = theValues->Value(i)*aCurLen;
243 GCPnts_AbscissaPoint anAbsc(aAdC,aLen,aFirst);
245 theValues->ChangeValue(i) = anAbsc.Parameter();
247 theValues->Remove(i--);
250 GCPnts_AbscissaPoint anAbsc(aAdC2d,aLen,aFirst);
252 theValues->ChangeValue(i) = anAbsc.Parameter();
254 theValues->Remove(i--);
258 return (theValues->Length());