1 // Created on: 1998-08-17
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepFill_ShapeLaw.ixx>
19 #include <BRepTools_WireExplorer.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepLProp.hxx>
25 #include <TopoDS_Vertex.hxx>
27 #include <Geom_Curve.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom_TrimmedCurve.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <GeomFill_UniformSection.hxx>
32 #include <GeomFill_EvolvedSection.hxx>
33 #include <GeomFill_HArray1OfSectionLaw.hxx>
34 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
36 #include <TColgp_HArray1OfPnt.hxx>
37 #include <TColStd_HArray1OfReal.hxx>
38 #include <TColStd_HArray1OfInteger.hxx>
41 #include <Precision.hxx>
44 //=======================================================================
46 //purpose : Process the case of Vertex by constructing a line
47 // with the vertex in the origin
48 //=======================================================================
49 BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Vertex& V,
50 const Standard_Boolean Build)
51 : vertex(Standard_True),
55 uclosed = Standard_False;
56 vclosed = Standard_True; // constant law
57 myEdges = new (TopTools_HArray1OfShape) (1, 1);
58 myEdges->SetValue(1, V);
61 myLaws = new (GeomFill_HArray1OfSectionLaw) (1, 1);
63 gp_Dir D(1,0,0); //Following the normal
64 Handle(Geom_Line) L = new (Geom_Line)(BRep_Tool::Pnt(V), D);
65 Standard_Real Last = 2*BRep_Tool::Tolerance(V)+Precision::PConfusion();
66 Handle(Geom_TrimmedCurve) TC = new (Geom_TrimmedCurve) (L, 0, Last);
68 myLaws->ChangeValue(1) =
69 new (GeomFill_UniformSection)(TC);
73 //=======================================================================
76 //=======================================================================
78 BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
79 const Standard_Boolean Build)
80 : vertex(Standard_False),
89 //=======================================================================
91 //purpose : Evolutive Wire
92 //=======================================================================
94 BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
95 const Handle(Law_Function)& L,
96 const Standard_Boolean Build)
97 : vertex(Standard_False),
105 //=======================================================================
107 //purpose : Case of the wire : Create a table of GeomFill_SectionLaw
108 //=======================================================================
109 void BRepFill_ShapeLaw::Init(const Standard_Boolean Build)
111 vclosed = Standard_True;
112 BRepTools_WireExplorer wexp;
114 Standard_Integer NbEdge,ii;
115 Standard_Real First, Last;
117 W = TopoDS::Wire(myShape);
119 for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next()) {
121 if( !E.IsNull() && !BRep_Tool::Degenerated(E)) {
122 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
129 myLaws = new GeomFill_HArray1OfSectionLaw (1, NbEdge);
130 myEdges = new TopTools_HArray1OfShape (1, NbEdge);
134 for(wexp.Init(W); wexp.More(); wexp.Next()) {
136 if ( !E.IsNull() && !BRep_Tool::Degenerated(wexp.Current())) {
137 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
139 myEdges->SetValue(ii, E);
141 //Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
142 if (E.Orientation() == TopAbs_REVERSED) {
144 Handle(Geom_Curve) CBis;
145 CBis = C->Reversed(); // To avoid the deterioration of the topology
146 aux = C->ReversedParameter(First);
147 First = C->ReversedParameter(Last);
152 Standard_Boolean IsReallyClosed = E.Closed();
153 //IFV - some checking when closed flag is wrong
155 TopoDS_Vertex V1, V2;
156 TopExp::Vertices(E, V1, V2);
157 if(V1.IsNull() || V2.IsNull()) {
158 IsReallyClosed = Standard_False;
161 IsReallyClosed = V1.IsSame(V2);
165 if ((ii>1) || !IsReallyClosed ) { // Trim C
166 Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(C,First, Last);
169 // otherwise preserve the integrity of the curve
170 if (TheLaw.IsNull()) {
171 myLaws->ChangeValue(ii) = new GeomFill_UniformSection(C);
174 myLaws->ChangeValue(ii) = new GeomFill_EvolvedSection(C, TheLaw);
182 // cout << "new law" << endl;
184 // Is the law closed by U ?
185 uclosed = W.Closed();
187 // if not sure about the flag, make check
188 TopoDS_Edge Edge1, Edge2;
190 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
191 Edge2 = TopoDS::Edge (myEdges->Value(1));
193 if( Edge1.Orientation() == TopAbs_REVERSED) {
194 V1 = TopExp::FirstVertex(Edge1);
197 V1 = TopExp::LastVertex(Edge1);
200 if ( Edge2.Orientation() == TopAbs_REVERSED) {
201 V2 = TopExp::LastVertex(Edge2);
204 V2 = TopExp::FirstVertex(Edge2);
207 uclosed = Standard_True;
210 BRepAdaptor_Curve Curve1(Edge1);
211 BRepAdaptor_Curve Curve2(Edge2);
212 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
213 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
214 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
215 BRep_Tool::Tolerance(V1);
217 uclosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
223 //=======================================================================
224 //function : IsVertex
226 //=======================================================================
227 Standard_Boolean BRepFill_ShapeLaw::IsVertex() const
232 //=======================================================================
233 //function : IsConstant
235 //=======================================================================
236 Standard_Boolean BRepFill_ShapeLaw::IsConstant() const
238 return TheLaw.IsNull();
241 //=======================================================================
244 //=======================================================================
246 BRepFill_ShapeLaw::Vertex(const Standard_Integer Index,
247 const Standard_Real Param) const
251 if (Index <= myEdges->Length()) {
252 E = TopoDS::Edge(myEdges->Value(Index));
253 if (E.Orientation() == TopAbs_REVERSED)
254 V = TopExp::LastVertex(E);
255 else V = TopExp::FirstVertex(E);
257 else if (Index == myEdges->Length()+1) {
258 E = TopoDS::Edge(myEdges->Value(Index-1));
259 if (E.Orientation() == TopAbs_REVERSED)
260 V = TopExp::FirstVertex(E);
261 else V = TopExp::LastVertex(E);
264 if (!TheLaw.IsNull()) {
266 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(Param));
267 TopLoc_Location L(T);
274 ///=======================================================================
275 //function : VertexTol
276 //purpose : Evaluate the hole between 2 edges of the section
277 //=======================================================================
278 Standard_Real BRepFill_ShapeLaw::VertexTol(const Standard_Integer Index,
279 const Standard_Real Param) const
281 Standard_Real Tol = Precision::Confusion();
282 Standard_Integer I1, I2;
283 if ( (Index==0) || (Index==myEdges->Length()) ) {
284 if (!uclosed) return Tol; //The least possible error
285 I1 = myEdges->Length();
293 Handle(GeomFill_SectionLaw) Loi;
294 Standard_Integer NbPoles, NbKnots, Degree;
295 Handle(TColgp_HArray1OfPnt) Poles;
296 Handle(TColStd_HArray1OfReal) Knots, Weigth;
297 Handle(TColStd_HArray1OfInteger) Mults;
298 Handle(Geom_BSplineCurve) BS;
301 Loi = myLaws->Value(I1);
302 Loi->SectionShape( NbPoles, NbKnots, Degree);
303 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
304 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
305 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
306 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
307 Loi->Knots(Knots->ChangeArray1());
308 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
309 Loi->Mults(Mults->ChangeArray1());
310 BS = new (Geom_BSplineCurve) (Poles->Array1(),
316 PFirst = BS->Value( Knots->Value(Knots->Length()) );
318 Loi = myLaws->Value(I2);
319 Loi->SectionShape( NbPoles, NbKnots, Degree);
320 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
321 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
322 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
323 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
324 Loi->Knots(Knots->ChangeArray1());
325 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
326 Loi->Mults(Mults->ChangeArray1());
327 BS = new (Geom_BSplineCurve) (Poles->Array1(),
333 Tol += PFirst.Distance(BS->Value( Knots->Value(1)));
337 //=======================================================================
338 //function : ConcatenedLaw
340 //=======================================================================
342 Handle(GeomFill_SectionLaw) BRepFill_ShapeLaw::ConcatenedLaw() const
344 Handle(GeomFill_SectionLaw) Law;
345 if (myLaws->Length() == 1)
346 return myLaws->Value(1);
350 W = TopoDS::Wire(myShape);
352 // Concatenation of edges
354 Standard_Real epsV, f, l;
355 Standard_Boolean Bof;
356 Handle(Geom_Curve) Composite;
357 Handle(Geom_TrimmedCurve) TC;
358 Composite = BRep_Tool::Curve(Edge(1), f, l);
359 TC = new (Geom_TrimmedCurve)(Composite, f, l);
360 GeomConvert_CompCurveToBSplineCurve Concat(TC);
362 for (ii=2, Bof=Standard_True; ii<=myEdges->Length() && Bof; ii++){
363 Composite = BRep_Tool::Curve(Edge(ii),f, l);
364 TC = new (Geom_TrimmedCurve)(Composite, f, l);
365 Bof = TopExp::CommonVertex(Edge(ii-1), Edge(ii), V);
366 if (Bof) {epsV = BRep_Tool::Tolerance(V);}
367 else epsV = 10*Precision::PConfusion();
368 Bof = Concat.Add(TC, epsV, Standard_True,
370 if (!Bof) Bof = Concat.Add(TC, 200*epsV,
371 Standard_True, Standard_False, 20);
374 cout << "BRepFill_ShapeLaw::ConcatenedLaw INCOMPLET !!!"
378 Composite = Concat.BSplineCurve();
380 if (TheLaw.IsNull()) {
381 Law = new (GeomFill_UniformSection)(Composite);
384 Law = new (GeomFill_EvolvedSection)(Composite, TheLaw);
391 //=======================================================================
392 //function : Continuity
394 //=======================================================================
395 GeomAbs_Shape BRepFill_ShapeLaw::Continuity(const Standard_Integer Index,
396 const Standard_Real TolAngular) const
399 TopoDS_Edge Edge1, Edge2;
400 if ( (Index==0) || (Index==myEdges->Length()) ) {
401 if (!uclosed) return GeomAbs_C0; //The least possible error
403 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
404 Edge2 = TopoDS::Edge (myEdges->Value(1));
407 Edge1 = TopoDS::Edge (myEdges->Value(Index));
408 Edge2 = TopoDS::Edge (myEdges->Value(Index+1));
412 if ( Edge1.Orientation() == TopAbs_REVERSED) {
413 V1 = TopExp::FirstVertex(Edge1);
416 V1 = TopExp::LastVertex(Edge1);
418 if ( Edge2.Orientation() == TopAbs_REVERSED) {
419 V2 = TopExp::LastVertex(Edge2);
422 V2 = TopExp::FirstVertex(Edge2);
425 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
426 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
427 BRepAdaptor_Curve Curve1(Edge1);
428 BRepAdaptor_Curve Curve2(Edge2);
429 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
430 BRep_Tool::Tolerance(V1);
432 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular);
437 //=======================================================================
440 //=======================================================================
441 void BRepFill_ShapeLaw::D0(const Standard_Real U, TopoDS_Shape& S)
444 if (!TheLaw.IsNull()) {
446 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(U));
447 TopLoc_Location L(T);