0024920: Invalid result of Pipe construction
[occt.git] / src / BRepFill / BRepFill_ShapeLaw.cxx
CommitLineData
b311480e 1// Created on: 1998-08-17
2// Created by: Philippe MANGIN
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <BRepFill_ShapeLaw.ixx>
18
19#include <BRepTools_WireExplorer.hxx>
20#include <BRep_Tool.hxx>
21#include <BRepAdaptor_Curve.hxx>
22#include <BRepLProp.hxx>
23#include <TopExp.hxx>
24#include <TopoDS.hxx>
25#include <TopoDS_Vertex.hxx>
26
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>
35
36#include <TColgp_HArray1OfPnt.hxx>
37#include <TColStd_HArray1OfReal.hxx>
38#include <TColStd_HArray1OfInteger.hxx>
39
7fd59977 40#include <Precision.hxx>
c8ea5b8e 41#include <BRepBuilderAPI_Transform.hxx>
7fd59977 42
43
44//=======================================================================
45//function : Create
0d969553
Y
46//purpose : Process the case of Vertex by constructing a line
47// with the vertex in the origin
7fd59977 48//=======================================================================
49BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Vertex& V,
50 const Standard_Boolean Build)
51 : vertex(Standard_True),
52 myShape(V)
53{
54 TheLaw.Nullify();
55 uclosed = Standard_False;
0d969553 56 vclosed = Standard_True; // constant law
7fd59977 57 myEdges = new (TopTools_HArray1OfShape) (1, 1);
58 myEdges->SetValue(1, V);
59
60 if (Build) {
61 myLaws = new (GeomFill_HArray1OfSectionLaw) (1, 1);
62// gp_Pnt Origine;
0d969553 63 gp_Dir D(1,0,0); //Following the normal
7fd59977 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);
67
68 myLaws->ChangeValue(1) =
69 new (GeomFill_UniformSection)(TC);
70 }
71}
72
73//=======================================================================
74//function : Create
75//purpose : Wire
76//=======================================================================
77
78BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
79 const Standard_Boolean Build)
80 : vertex(Standard_False),
81 myShape(W)
82
83
84{
85 TheLaw.Nullify();
86 Init(Build);
87}
88
89//=======================================================================
90//function : Create
0d969553 91//purpose : Evolutive Wire
7fd59977 92//=======================================================================
93
94BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
95 const Handle(Law_Function)& L,
96 const Standard_Boolean Build)
97 : vertex(Standard_False),
98 myShape(W)
99
100{
101 TheLaw = L;
102 Init(Build);
103}
104
105//=======================================================================
106//function : Init
0d969553 107//purpose : Case of the wire : Create a table of GeomFill_SectionLaw
7fd59977 108//=======================================================================
109void BRepFill_ShapeLaw::Init(const Standard_Boolean Build)
110{
111 vclosed = Standard_True;
112 BRepTools_WireExplorer wexp;
113 TopoDS_Edge E;
114 Standard_Integer NbEdge,ii;
115 Standard_Real First, Last;
116 TopoDS_Wire W;
117 W = TopoDS::Wire(myShape);
118
119 for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next()) {
120 E = wexp.Current();
121 if( !E.IsNull() && !BRep_Tool::Degenerated(E)) {
122 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
123 if( !C.IsNull() ) {
124 NbEdge++;
125 }
126 }
127 }
128
129 myLaws = new GeomFill_HArray1OfSectionLaw (1, NbEdge);
130 myEdges = new TopTools_HArray1OfShape (1, NbEdge);
131
132 ii = 1;
133
134 for(wexp.Init(W); wexp.More(); wexp.Next()) {
135 E = wexp.Current();
136 if ( !E.IsNull() && !BRep_Tool::Degenerated(wexp.Current())) {
137 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
138 if( !C.IsNull() ) {
139 myEdges->SetValue(ii, E);
140 if(Build) {
141 //Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
142 if (E.Orientation() == TopAbs_REVERSED) {
143 Standard_Real aux;
144 Handle(Geom_Curve) CBis;
0d969553 145 CBis = C->Reversed(); // To avoid the deterioration of the topology
7fd59977 146 aux = C->ReversedParameter(First);
147 First = C->ReversedParameter(Last);
148 Last = aux;
149 C = CBis;
150 }
151
152 Standard_Boolean IsReallyClosed = E.Closed();
153 //IFV - some checking when closed flag is wrong
154 if(IsReallyClosed) {
155 TopoDS_Vertex V1, V2;
156 TopExp::Vertices(E, V1, V2);
157 if(V1.IsNull() || V2.IsNull()) {
158 IsReallyClosed = Standard_False;
159 }
160 else {
161 IsReallyClosed = V1.IsSame(V2);
162 }
163 }
d9203559 164 if (IsReallyClosed &&
165 Abs(C->FirstParameter() - First) > Precision::PConfusion())
166 IsReallyClosed = Standard_False; //trimmed curve differs
7fd59977 167
0d969553 168 if ((ii>1) || !IsReallyClosed ) { // Trim C
7fd59977 169 Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(C,First, Last);
170 C = TC;
171 }
0d969553 172 // otherwise preserve the integrity of the curve
7fd59977 173 if (TheLaw.IsNull()) {
174 myLaws->ChangeValue(ii) = new GeomFill_UniformSection(C);
175 }
176 else {
177 myLaws->ChangeValue(ii) = new GeomFill_EvolvedSection(C, TheLaw);
178 }
179 }
180 ii++;
181 }
182 }
183 }
184
185// cout << "new law" << endl;
186
0d969553 187 // Is the law closed by U ?
7fd59977 188 uclosed = W.Closed();
189 if (!uclosed) {
0d969553 190 // if not sure about the flag, make check
7fd59977 191 TopoDS_Edge Edge1, Edge2;
192 TopoDS_Vertex V1,V2;
193 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
194 Edge2 = TopoDS::Edge (myEdges->Value(1));
195
196 if( Edge1.Orientation() == TopAbs_REVERSED) {
197 V1 = TopExp::FirstVertex(Edge1);
198 }
199 else {
200 V1 = TopExp::LastVertex(Edge1);
201 }
202
203 if ( Edge2.Orientation() == TopAbs_REVERSED) {
204 V2 = TopExp::LastVertex(Edge2);
205 }
206 else {
207 V2 = TopExp::FirstVertex(Edge2);
208 }
209 if (V1.IsSame(V2)) {
210 uclosed = Standard_True;
211 }
212 else {
213 BRepAdaptor_Curve Curve1(Edge1);
214 BRepAdaptor_Curve Curve2(Edge2);
215 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
216 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
217 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
218 BRep_Tool::Tolerance(V1);
219
220 uclosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
221 }
222 }
223}
224
225
226//=======================================================================
227//function : IsVertex
228//purpose :
229//=======================================================================
230 Standard_Boolean BRepFill_ShapeLaw::IsVertex() const
231{
232 return vertex;
233}
234
235//=======================================================================
236//function : IsConstant
237//purpose :
238//=======================================================================
239 Standard_Boolean BRepFill_ShapeLaw::IsConstant() const
240{
241 return TheLaw.IsNull();
242}
243
244//=======================================================================
245//function : Vertex
246//purpose :
247//=======================================================================
248 TopoDS_Vertex
249 BRepFill_ShapeLaw::Vertex(const Standard_Integer Index,
250 const Standard_Real Param) const
251{
252 TopoDS_Edge E;
253 TopoDS_Vertex V;
254 if (Index <= myEdges->Length()) {
255 E = TopoDS::Edge(myEdges->Value(Index));
256 if (E.Orientation() == TopAbs_REVERSED)
257 V = TopExp::LastVertex(E);
258 else V = TopExp::FirstVertex(E);
259 }
260 else if (Index == myEdges->Length()+1) {
261 E = TopoDS::Edge(myEdges->Value(Index-1));
262 if (E.Orientation() == TopAbs_REVERSED)
263 V = TopExp::FirstVertex(E);
264 else V = TopExp::LastVertex(E);
265 }
266
267 if (!TheLaw.IsNull()) {
268 gp_Trsf T;
269 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(Param));
c8ea5b8e 270 //TopLoc_Location L(T);
271 //V.Move(L);
272 V = TopoDS::Vertex(BRepBuilderAPI_Transform(V, T));
7fd59977 273 }
274 return V;
275}
276
277
278///=======================================================================
279//function : VertexTol
0d969553 280//purpose : Evaluate the hole between 2 edges of the section
7fd59977 281//=======================================================================
282 Standard_Real BRepFill_ShapeLaw::VertexTol(const Standard_Integer Index,
283 const Standard_Real Param) const
284{
285 Standard_Real Tol = Precision::Confusion();
286 Standard_Integer I1, I2;
287 if ( (Index==0) || (Index==myEdges->Length()) ) {
0d969553 288 if (!uclosed) return Tol; //The least possible error
7fd59977 289 I1 = myEdges->Length();
290 I2 = 1;
291 }
292 else {
293 I1 = Index;
294 I2 = I1 +1;
295 }
296
297 Handle(GeomFill_SectionLaw) Loi;
298 Standard_Integer NbPoles, NbKnots, Degree;
299 Handle(TColgp_HArray1OfPnt) Poles;
300 Handle(TColStd_HArray1OfReal) Knots, Weigth;
301 Handle(TColStd_HArray1OfInteger) Mults;
302 Handle(Geom_BSplineCurve) BS;
303 gp_Pnt PFirst;
304
305 Loi = myLaws->Value(I1);
306 Loi->SectionShape( NbPoles, NbKnots, Degree);
307 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
308 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
309 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
310 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
311 Loi->Knots(Knots->ChangeArray1());
312 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
313 Loi->Mults(Mults->ChangeArray1());
314 BS = new (Geom_BSplineCurve) (Poles->Array1(),
315 Weigth->Array1(),
316 Knots->Array1(),
317 Mults->Array1(),
318 Degree,
319 Loi->IsUPeriodic());
320 PFirst = BS->Value( Knots->Value(Knots->Length()) );
321
322 Loi = myLaws->Value(I2);
323 Loi->SectionShape( NbPoles, NbKnots, Degree);
324 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
325 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
326 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
327 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
328 Loi->Knots(Knots->ChangeArray1());
329 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
330 Loi->Mults(Mults->ChangeArray1());
331 BS = new (Geom_BSplineCurve) (Poles->Array1(),
332 Weigth->Array1(),
333 Knots->Array1(),
334 Mults->Array1(),
335 Degree,
336 Loi->IsUPeriodic());
337 Tol += PFirst.Distance(BS->Value( Knots->Value(1)));
338 return Tol;
339}
340
341//=======================================================================
342//function : ConcatenedLaw
343//purpose :
344//=======================================================================
345
346 Handle(GeomFill_SectionLaw) BRepFill_ShapeLaw::ConcatenedLaw() const
347{
348 Handle(GeomFill_SectionLaw) Law;
349 if (myLaws->Length() == 1)
350 return myLaws->Value(1);
351 else {
352 TopoDS_Wire W;
353 TopoDS_Vertex V;
354 W = TopoDS::Wire(myShape);
355 if(!W.IsNull()) {
0d969553 356 // Concatenation of edges
7fd59977 357 Standard_Integer ii;
358 Standard_Real epsV, f, l;
359 Standard_Boolean Bof;
360 Handle(Geom_Curve) Composite;
361 Handle(Geom_TrimmedCurve) TC;
362 Composite = BRep_Tool::Curve(Edge(1), f, l);
363 TC = new (Geom_TrimmedCurve)(Composite, f, l);
364 GeomConvert_CompCurveToBSplineCurve Concat(TC);
365
366 for (ii=2, Bof=Standard_True; ii<=myEdges->Length() && Bof; ii++){
367 Composite = BRep_Tool::Curve(Edge(ii),f, l);
368 TC = new (Geom_TrimmedCurve)(Composite, f, l);
369 Bof = TopExp::CommonVertex(Edge(ii-1), Edge(ii), V);
370 if (Bof) {epsV = BRep_Tool::Tolerance(V);}
371 else epsV = 10*Precision::PConfusion();
372 Bof = Concat.Add(TC, epsV, Standard_True,
373 Standard_False, 20);
374 if (!Bof) Bof = Concat.Add(TC, 200*epsV,
375 Standard_True, Standard_False, 20);
376#if DEB
377 if (!Bof)
378 cout << "BRepFill_ShapeLaw::ConcatenedLaw INCOMPLET !!!"
379 << endl;
380#endif
381 }
382 Composite = Concat.BSplineCurve();
383
384 if (TheLaw.IsNull()) {
385 Law = new (GeomFill_UniformSection)(Composite);
386 }
387 else {
388 Law = new (GeomFill_EvolvedSection)(Composite, TheLaw);
389 }
390 }
391 }
392 return Law;
393}
394
395//=======================================================================
396//function : Continuity
397//purpose :
398//=======================================================================
399 GeomAbs_Shape BRepFill_ShapeLaw::Continuity(const Standard_Integer Index,
400 const Standard_Real TolAngular) const
401{
402
c8ea5b8e 403 TopoDS_Edge Edge1, Edge2;
7fd59977 404 if ( (Index==0) || (Index==myEdges->Length()) ) {
0d969553 405 if (!uclosed) return GeomAbs_C0; //The least possible error
c8ea5b8e 406
7fd59977 407 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
408 Edge2 = TopoDS::Edge (myEdges->Value(1));
409 }
410 else {
411 Edge1 = TopoDS::Edge (myEdges->Value(Index));
412 Edge2 = TopoDS::Edge (myEdges->Value(Index+1));
413 }
c8ea5b8e 414
415 TopoDS_Vertex V1,V2; //common vertex
416 TopoDS_Vertex vv1, vv2, vv3, vv4;
417 TopExp::Vertices(Edge1, vv1, vv2);
418 TopExp::Vertices(Edge2, vv3, vv4);
419 if (vv1.IsSame(vv3))
420 { V1 = vv1; V2 = vv3; }
421 else if (vv1.IsSame(vv4))
422 { V1 = vv1; V2 = vv4; }
423 else if (vv2.IsSame(vv3))
424 { V1 = vv2; V2 = vv3; }
425 else
426 { V1 = vv2; V2 = vv4; }
7fd59977 427
428 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
429 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
430 BRepAdaptor_Curve Curve1(Edge1);
431 BRepAdaptor_Curve Curve2(Edge2);
432 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
433 BRep_Tool::Tolerance(V1);
434 GeomAbs_Shape cont;
435 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular);
436
437 return cont;
438}
439
440//=======================================================================
441//function : D0
442//purpose :
443//=======================================================================
444 void BRepFill_ShapeLaw::D0(const Standard_Real U, TopoDS_Shape& S)
445{
446 S = myShape;
447 if (!TheLaw.IsNull()) {
448 gp_Trsf T;
449 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(U));
c8ea5b8e 450 //TopLoc_Location L(T);
451 //S.Move(L);
452 S = BRepBuilderAPI_Transform(S, T);
7fd59977 453 }
454}