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 under
9 // the terms of the GNU Lesser General Public License 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.
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepBuilderAPI_Transform.hxx>
21 #include <BRepFill_ShapeLaw.hxx>
22 #include <BRepLProp.hxx>
23 #include <BRepTools_WireExplorer.hxx>
24 #include <Geom_BSplineCurve.hxx>
25 #include <Geom_Curve.hxx>
26 #include <Geom_Line.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
29 #include <GeomFill_EvolvedSection.hxx>
30 #include <GeomFill_HArray1OfSectionLaw.hxx>
31 #include <GeomFill_SectionLaw.hxx>
32 #include <GeomFill_UniformSection.hxx>
33 #include <Law_Function.hxx>
34 #include <Precision.hxx>
35 #include <Standard_Type.hxx>
36 #include <TColgp_HArray1OfPnt.hxx>
37 #include <TColStd_HArray1OfInteger.hxx>
38 #include <TColStd_HArray1OfReal.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopoDS_Wire.hxx>
46 //=======================================================================
48 //purpose : Process the case of Vertex by constructing a line
49 // with the vertex in the origin
50 //=======================================================================
51 BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Vertex& V,
52 const Standard_Boolean Build)
53 : vertex(Standard_True),
57 uclosed = Standard_False;
58 vclosed = Standard_True; // constant law
59 myEdges = new (TopTools_HArray1OfShape) (1, 1);
60 myEdges->SetValue(1, V);
63 myLaws = new (GeomFill_HArray1OfSectionLaw) (1, 1);
65 gp_Dir D(1,0,0); //Following the normal
66 Handle(Geom_Line) L = new (Geom_Line)(BRep_Tool::Pnt(V), D);
67 Standard_Real Last = 2*BRep_Tool::Tolerance(V)+Precision::PConfusion();
68 Handle(Geom_TrimmedCurve) TC = new (Geom_TrimmedCurve) (L, 0, Last);
70 myLaws->ChangeValue(1) =
71 new (GeomFill_UniformSection)(TC);
75 //=======================================================================
78 //=======================================================================
80 BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
81 const Standard_Boolean Build)
82 : vertex(Standard_False),
91 //=======================================================================
93 //purpose : Evolutive Wire
94 //=======================================================================
96 BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
97 const Handle(Law_Function)& L,
98 const Standard_Boolean Build)
99 : vertex(Standard_False),
107 //=======================================================================
109 //purpose : Case of the wire : Create a table of GeomFill_SectionLaw
110 //=======================================================================
111 void BRepFill_ShapeLaw::Init(const Standard_Boolean Build)
113 vclosed = Standard_True;
114 BRepTools_WireExplorer wexp;
116 Standard_Integer NbEdge,ii;
117 Standard_Real First, Last;
119 W = TopoDS::Wire(myShape);
121 for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next()) {
123 if( !E.IsNull() && !BRep_Tool::Degenerated(E)) {
124 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
131 myLaws = new GeomFill_HArray1OfSectionLaw (1, NbEdge);
132 myEdges = new TopTools_HArray1OfShape (1, NbEdge);
136 for(wexp.Init(W); wexp.More(); wexp.Next()) {
138 if ( !E.IsNull() && !BRep_Tool::Degenerated(wexp.Current())) {
139 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
141 myEdges->SetValue(ii, E);
143 //Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
144 if (E.Orientation() == TopAbs_REVERSED) {
146 Handle(Geom_Curve) CBis;
147 CBis = C->Reversed(); // To avoid the deterioration of the topology
148 aux = C->ReversedParameter(First);
149 First = C->ReversedParameter(Last);
154 Standard_Boolean IsClosed = BRep_Tool::IsClosed(E);
156 Abs(C->FirstParameter() - First) > Precision::PConfusion())
157 IsClosed = Standard_False; //trimmed curve differs
159 if ((ii>1) || !IsClosed ) { // Trim C
160 Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(C,First, Last);
163 // otherwise preserve the integrity of the curve
164 if (TheLaw.IsNull()) {
165 myLaws->ChangeValue(ii) = new GeomFill_UniformSection(C);
168 myLaws->ChangeValue(ii) = new GeomFill_EvolvedSection(C, TheLaw);
176 // cout << "new law" << endl;
178 // Is the law closed by U ?
179 uclosed = W.Closed();
181 // if not sure about the flag, make check
182 TopoDS_Edge Edge1, Edge2;
184 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
185 Edge2 = TopoDS::Edge (myEdges->Value(1));
187 if( Edge1.Orientation() == TopAbs_REVERSED) {
188 V1 = TopExp::FirstVertex(Edge1);
191 V1 = TopExp::LastVertex(Edge1);
194 if ( Edge2.Orientation() == TopAbs_REVERSED) {
195 V2 = TopExp::LastVertex(Edge2);
198 V2 = TopExp::FirstVertex(Edge2);
201 uclosed = Standard_True;
204 BRepAdaptor_Curve Curve1(Edge1);
205 BRepAdaptor_Curve Curve2(Edge2);
206 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
207 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
208 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
209 BRep_Tool::Tolerance(V1);
211 uclosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
217 //=======================================================================
218 //function : IsVertex
220 //=======================================================================
221 Standard_Boolean BRepFill_ShapeLaw::IsVertex() const
226 //=======================================================================
227 //function : IsConstant
229 //=======================================================================
230 Standard_Boolean BRepFill_ShapeLaw::IsConstant() const
232 return TheLaw.IsNull();
235 //=======================================================================
238 //=======================================================================
240 BRepFill_ShapeLaw::Vertex(const Standard_Integer Index,
241 const Standard_Real Param) const
245 if (Index <= myEdges->Length()) {
246 E = TopoDS::Edge(myEdges->Value(Index));
247 if (E.Orientation() == TopAbs_REVERSED)
248 V = TopExp::LastVertex(E);
249 else V = TopExp::FirstVertex(E);
251 else if (Index == myEdges->Length()+1) {
252 E = TopoDS::Edge(myEdges->Value(Index-1));
253 if (E.Orientation() == TopAbs_REVERSED)
254 V = TopExp::FirstVertex(E);
255 else V = TopExp::LastVertex(E);
258 if (!TheLaw.IsNull()) {
260 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(Param));
261 //TopLoc_Location L(T);
263 V = TopoDS::Vertex(BRepBuilderAPI_Transform(V, T));
269 ///=======================================================================
270 //function : VertexTol
271 //purpose : Evaluate the hole between 2 edges of the section
272 //=======================================================================
273 Standard_Real BRepFill_ShapeLaw::VertexTol(const Standard_Integer Index,
274 const Standard_Real Param) const
276 Standard_Real Tol = Precision::Confusion();
277 Standard_Integer I1, I2;
278 if ( (Index==0) || (Index==myEdges->Length()) ) {
279 if (!uclosed) return Tol; //The least possible error
280 I1 = myEdges->Length();
288 Handle(GeomFill_SectionLaw) Loi;
289 Standard_Integer NbPoles, NbKnots, Degree;
290 Handle(TColgp_HArray1OfPnt) Poles;
291 Handle(TColStd_HArray1OfReal) Knots, Weigth;
292 Handle(TColStd_HArray1OfInteger) Mults;
293 Handle(Geom_BSplineCurve) BS;
296 Loi = myLaws->Value(I1);
297 Loi->SectionShape( NbPoles, NbKnots, Degree);
298 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
299 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
300 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
301 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
302 Loi->Knots(Knots->ChangeArray1());
303 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
304 Loi->Mults(Mults->ChangeArray1());
305 BS = new (Geom_BSplineCurve) (Poles->Array1(),
311 PFirst = BS->Value( Knots->Value(Knots->Length()) );
313 Loi = myLaws->Value(I2);
314 Loi->SectionShape( NbPoles, NbKnots, Degree);
315 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
316 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
317 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
318 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
319 Loi->Knots(Knots->ChangeArray1());
320 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
321 Loi->Mults(Mults->ChangeArray1());
322 BS = new (Geom_BSplineCurve) (Poles->Array1(),
328 Tol += PFirst.Distance(BS->Value( Knots->Value(1)));
332 //=======================================================================
333 //function : ConcatenedLaw
335 //=======================================================================
337 Handle(GeomFill_SectionLaw) BRepFill_ShapeLaw::ConcatenedLaw() const
339 Handle(GeomFill_SectionLaw) Law;
340 if (myLaws->Length() == 1)
341 return myLaws->Value(1);
345 W = TopoDS::Wire(myShape);
347 // Concatenation of edges
349 Standard_Real epsV, f, l;
350 Standard_Boolean Bof;
351 Handle(Geom_Curve) Composite;
352 Handle(Geom_TrimmedCurve) TC;
353 Composite = BRep_Tool::Curve(Edge(1), f, l);
354 TC = new (Geom_TrimmedCurve)(Composite, f, l);
355 GeomConvert_CompCurveToBSplineCurve Concat(TC);
357 for (ii=2, Bof=Standard_True; ii<=myEdges->Length() && Bof; ii++){
358 Composite = BRep_Tool::Curve(Edge(ii),f, l);
359 TC = new (Geom_TrimmedCurve)(Composite, f, l);
360 Bof = TopExp::CommonVertex(Edge(ii-1), Edge(ii), V);
361 if (Bof) {epsV = BRep_Tool::Tolerance(V);}
362 else epsV = 10*Precision::PConfusion();
363 Bof = Concat.Add(TC, epsV, Standard_True,
365 if (!Bof) Bof = Concat.Add(TC, 200*epsV,
366 Standard_True, Standard_False, 20);
369 cout << "BRepFill_ShapeLaw::ConcatenedLaw INCOMPLET !!!"
373 Composite = Concat.BSplineCurve();
375 if (TheLaw.IsNull()) {
376 Law = new (GeomFill_UniformSection)(Composite);
379 Law = new (GeomFill_EvolvedSection)(Composite, TheLaw);
386 //=======================================================================
387 //function : Continuity
389 //=======================================================================
390 GeomAbs_Shape BRepFill_ShapeLaw::Continuity(const Standard_Integer Index,
391 const Standard_Real TolAngular) const
394 TopoDS_Edge Edge1, Edge2;
395 if ( (Index==0) || (Index==myEdges->Length()) ) {
396 if (!uclosed) return GeomAbs_C0; //The least possible error
398 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
399 Edge2 = TopoDS::Edge (myEdges->Value(1));
402 Edge1 = TopoDS::Edge (myEdges->Value(Index));
403 Edge2 = TopoDS::Edge (myEdges->Value(Index+1));
406 TopoDS_Vertex V1,V2; //common vertex
407 TopoDS_Vertex vv1, vv2, vv3, vv4;
408 TopExp::Vertices(Edge1, vv1, vv2);
409 TopExp::Vertices(Edge2, vv3, vv4);
411 { V1 = vv1; V2 = vv3; }
412 else if (vv1.IsSame(vv4))
413 { V1 = vv1; V2 = vv4; }
414 else if (vv2.IsSame(vv3))
415 { V1 = vv2; V2 = vv3; }
417 { V1 = vv2; V2 = vv4; }
419 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
420 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
421 BRepAdaptor_Curve Curve1(Edge1);
422 BRepAdaptor_Curve Curve2(Edge2);
423 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
424 BRep_Tool::Tolerance(V1);
426 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular);
431 //=======================================================================
434 //=======================================================================
435 void BRepFill_ShapeLaw::D0(const Standard_Real U, TopoDS_Shape& S)
438 if (!TheLaw.IsNull()) {
440 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(U));
441 //TopLoc_Location L(T);
443 S = BRepBuilderAPI_Transform(S, T);