0024002: Overall code and build procedure refactoring -- automatic
[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
7fd59977 17
7fd59977 18#include <BRep_Tool.hxx>
19#include <BRepAdaptor_Curve.hxx>
42cf5bc1 20#include <BRepBuilderAPI_Transform.hxx>
21#include <BRepFill_ShapeLaw.hxx>
7fd59977 22#include <BRepLProp.hxx>
42cf5bc1 23#include <BRepTools_WireExplorer.hxx>
24#include <Geom_BSplineCurve.hxx>
7fd59977 25#include <Geom_Curve.hxx>
26#include <Geom_Line.hxx>
27#include <Geom_TrimmedCurve.hxx>
42cf5bc1 28#include <GeomConvert_CompCurveToBSplineCurve.hxx>
7fd59977 29#include <GeomFill_EvolvedSection.hxx>
30#include <GeomFill_HArray1OfSectionLaw.hxx>
42cf5bc1 31#include <GeomFill_SectionLaw.hxx>
32#include <GeomFill_UniformSection.hxx>
33#include <Law_Function.hxx>
34#include <Precision.hxx>
35#include <Standard_Type.hxx>
7fd59977 36#include <TColgp_HArray1OfPnt.hxx>
7fd59977 37#include <TColStd_HArray1OfInteger.hxx>
42cf5bc1 38#include <TColStd_HArray1OfReal.hxx>
39#include <TopExp.hxx>
40#include <TopoDS.hxx>
41#include <TopoDS_Edge.hxx>
42#include <TopoDS_Shape.hxx>
43#include <TopoDS_Vertex.hxx>
44#include <TopoDS_Wire.hxx>
7fd59977 45
46//=======================================================================
47//function : Create
0d969553
Y
48//purpose : Process the case of Vertex by constructing a line
49// with the vertex in the origin
7fd59977 50//=======================================================================
51BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Vertex& V,
52 const Standard_Boolean Build)
53 : vertex(Standard_True),
54 myShape(V)
55{
56 TheLaw.Nullify();
57 uclosed = Standard_False;
0d969553 58 vclosed = Standard_True; // constant law
7fd59977 59 myEdges = new (TopTools_HArray1OfShape) (1, 1);
60 myEdges->SetValue(1, V);
61
62 if (Build) {
63 myLaws = new (GeomFill_HArray1OfSectionLaw) (1, 1);
64// gp_Pnt Origine;
0d969553 65 gp_Dir D(1,0,0); //Following the normal
7fd59977 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);
69
70 myLaws->ChangeValue(1) =
71 new (GeomFill_UniformSection)(TC);
72 }
73}
74
75//=======================================================================
76//function : Create
77//purpose : Wire
78//=======================================================================
79
80BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
81 const Standard_Boolean Build)
82 : vertex(Standard_False),
83 myShape(W)
84
85
86{
87 TheLaw.Nullify();
88 Init(Build);
89}
90
91//=======================================================================
92//function : Create
0d969553 93//purpose : Evolutive Wire
7fd59977 94//=======================================================================
95
96BRepFill_ShapeLaw::BRepFill_ShapeLaw(const TopoDS_Wire& W,
97 const Handle(Law_Function)& L,
98 const Standard_Boolean Build)
99 : vertex(Standard_False),
100 myShape(W)
101
102{
103 TheLaw = L;
104 Init(Build);
105}
106
107//=======================================================================
108//function : Init
0d969553 109//purpose : Case of the wire : Create a table of GeomFill_SectionLaw
7fd59977 110//=======================================================================
111void BRepFill_ShapeLaw::Init(const Standard_Boolean Build)
112{
113 vclosed = Standard_True;
114 BRepTools_WireExplorer wexp;
115 TopoDS_Edge E;
116 Standard_Integer NbEdge,ii;
117 Standard_Real First, Last;
118 TopoDS_Wire W;
119 W = TopoDS::Wire(myShape);
120
121 for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next()) {
122 E = wexp.Current();
123 if( !E.IsNull() && !BRep_Tool::Degenerated(E)) {
124 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
125 if( !C.IsNull() ) {
126 NbEdge++;
127 }
128 }
129 }
130
131 myLaws = new GeomFill_HArray1OfSectionLaw (1, NbEdge);
132 myEdges = new TopTools_HArray1OfShape (1, NbEdge);
133
134 ii = 1;
135
136 for(wexp.Init(W); wexp.More(); wexp.Next()) {
137 E = wexp.Current();
138 if ( !E.IsNull() && !BRep_Tool::Degenerated(wexp.Current())) {
139 Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
140 if( !C.IsNull() ) {
141 myEdges->SetValue(ii, E);
142 if(Build) {
143 //Handle(Geom_Curve) C = BRep_Tool::Curve(E,First,Last);
144 if (E.Orientation() == TopAbs_REVERSED) {
145 Standard_Real aux;
146 Handle(Geom_Curve) CBis;
0d969553 147 CBis = C->Reversed(); // To avoid the deterioration of the topology
7fd59977 148 aux = C->ReversedParameter(First);
149 First = C->ReversedParameter(Last);
150 Last = aux;
151 C = CBis;
152 }
153
da72a17c 154 Standard_Boolean IsClosed = BRep_Tool::IsClosed(E);
155 if (IsClosed &&
d9203559 156 Abs(C->FirstParameter() - First) > Precision::PConfusion())
da72a17c 157 IsClosed = Standard_False; //trimmed curve differs
7fd59977 158
da72a17c 159 if ((ii>1) || !IsClosed ) { // Trim C
7fd59977 160 Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(C,First, Last);
161 C = TC;
162 }
0d969553 163 // otherwise preserve the integrity of the curve
7fd59977 164 if (TheLaw.IsNull()) {
165 myLaws->ChangeValue(ii) = new GeomFill_UniformSection(C);
166 }
167 else {
168 myLaws->ChangeValue(ii) = new GeomFill_EvolvedSection(C, TheLaw);
169 }
170 }
171 ii++;
172 }
173 }
174 }
175
176// cout << "new law" << endl;
177
0d969553 178 // Is the law closed by U ?
7fd59977 179 uclosed = W.Closed();
180 if (!uclosed) {
0d969553 181 // if not sure about the flag, make check
7fd59977 182 TopoDS_Edge Edge1, Edge2;
183 TopoDS_Vertex V1,V2;
184 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
185 Edge2 = TopoDS::Edge (myEdges->Value(1));
186
187 if( Edge1.Orientation() == TopAbs_REVERSED) {
188 V1 = TopExp::FirstVertex(Edge1);
189 }
190 else {
191 V1 = TopExp::LastVertex(Edge1);
192 }
193
194 if ( Edge2.Orientation() == TopAbs_REVERSED) {
195 V2 = TopExp::LastVertex(Edge2);
196 }
197 else {
198 V2 = TopExp::FirstVertex(Edge2);
199 }
200 if (V1.IsSame(V2)) {
201 uclosed = Standard_True;
202 }
203 else {
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);
210
211 uclosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
212 }
213 }
214}
215
216
217//=======================================================================
218//function : IsVertex
219//purpose :
220//=======================================================================
221 Standard_Boolean BRepFill_ShapeLaw::IsVertex() const
222{
223 return vertex;
224}
225
226//=======================================================================
227//function : IsConstant
228//purpose :
229//=======================================================================
230 Standard_Boolean BRepFill_ShapeLaw::IsConstant() const
231{
232 return TheLaw.IsNull();
233}
234
235//=======================================================================
236//function : Vertex
237//purpose :
238//=======================================================================
239 TopoDS_Vertex
240 BRepFill_ShapeLaw::Vertex(const Standard_Integer Index,
241 const Standard_Real Param) const
242{
243 TopoDS_Edge E;
244 TopoDS_Vertex V;
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);
250 }
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);
256 }
257
258 if (!TheLaw.IsNull()) {
259 gp_Trsf T;
260 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(Param));
c8ea5b8e 261 //TopLoc_Location L(T);
262 //V.Move(L);
263 V = TopoDS::Vertex(BRepBuilderAPI_Transform(V, T));
7fd59977 264 }
265 return V;
266}
267
268
269///=======================================================================
270//function : VertexTol
0d969553 271//purpose : Evaluate the hole between 2 edges of the section
7fd59977 272//=======================================================================
273 Standard_Real BRepFill_ShapeLaw::VertexTol(const Standard_Integer Index,
274 const Standard_Real Param) const
275{
276 Standard_Real Tol = Precision::Confusion();
277 Standard_Integer I1, I2;
278 if ( (Index==0) || (Index==myEdges->Length()) ) {
0d969553 279 if (!uclosed) return Tol; //The least possible error
7fd59977 280 I1 = myEdges->Length();
281 I2 = 1;
282 }
283 else {
284 I1 = Index;
285 I2 = I1 +1;
286 }
287
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;
294 gp_Pnt PFirst;
295
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(),
306 Weigth->Array1(),
307 Knots->Array1(),
308 Mults->Array1(),
309 Degree,
310 Loi->IsUPeriodic());
311 PFirst = BS->Value( Knots->Value(Knots->Length()) );
312
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(),
323 Weigth->Array1(),
324 Knots->Array1(),
325 Mults->Array1(),
326 Degree,
327 Loi->IsUPeriodic());
328 Tol += PFirst.Distance(BS->Value( Knots->Value(1)));
329 return Tol;
330}
331
332//=======================================================================
333//function : ConcatenedLaw
334//purpose :
335//=======================================================================
336
337 Handle(GeomFill_SectionLaw) BRepFill_ShapeLaw::ConcatenedLaw() const
338{
339 Handle(GeomFill_SectionLaw) Law;
340 if (myLaws->Length() == 1)
341 return myLaws->Value(1);
342 else {
343 TopoDS_Wire W;
344 TopoDS_Vertex V;
345 W = TopoDS::Wire(myShape);
346 if(!W.IsNull()) {
0d969553 347 // Concatenation of edges
7fd59977 348 Standard_Integer ii;
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);
356
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,
364 Standard_False, 20);
365 if (!Bof) Bof = Concat.Add(TC, 200*epsV,
366 Standard_True, Standard_False, 20);
0797d9d3 367#ifdef OCCT_DEBUG
7fd59977 368 if (!Bof)
369 cout << "BRepFill_ShapeLaw::ConcatenedLaw INCOMPLET !!!"
370 << endl;
371#endif
372 }
373 Composite = Concat.BSplineCurve();
374
375 if (TheLaw.IsNull()) {
376 Law = new (GeomFill_UniformSection)(Composite);
377 }
378 else {
379 Law = new (GeomFill_EvolvedSection)(Composite, TheLaw);
380 }
381 }
382 }
383 return Law;
384}
385
386//=======================================================================
387//function : Continuity
388//purpose :
389//=======================================================================
390 GeomAbs_Shape BRepFill_ShapeLaw::Continuity(const Standard_Integer Index,
391 const Standard_Real TolAngular) const
392{
393
c8ea5b8e 394 TopoDS_Edge Edge1, Edge2;
7fd59977 395 if ( (Index==0) || (Index==myEdges->Length()) ) {
0d969553 396 if (!uclosed) return GeomAbs_C0; //The least possible error
c8ea5b8e 397
7fd59977 398 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
399 Edge2 = TopoDS::Edge (myEdges->Value(1));
400 }
401 else {
402 Edge1 = TopoDS::Edge (myEdges->Value(Index));
403 Edge2 = TopoDS::Edge (myEdges->Value(Index+1));
404 }
c8ea5b8e 405
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);
410 if (vv1.IsSame(vv3))
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; }
416 else
417 { V1 = vv2; V2 = vv4; }
7fd59977 418
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);
425 GeomAbs_Shape cont;
426 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular);
427
428 return cont;
429}
430
431//=======================================================================
432//function : D0
433//purpose :
434//=======================================================================
435 void BRepFill_ShapeLaw::D0(const Standard_Real U, TopoDS_Shape& S)
436{
437 S = myShape;
438 if (!TheLaw.IsNull()) {
439 gp_Trsf T;
440 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(U));
c8ea5b8e 441 //TopLoc_Location L(T);
442 //S.Move(L);
443 S = BRepBuilderAPI_Transform(S, T);
7fd59977 444 }
445}