0025656: Specification of semantic of Closed flag of an edge
[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
da72a17c 152 Standard_Boolean IsClosed = BRep_Tool::IsClosed(E);
153 if (IsClosed &&
d9203559 154 Abs(C->FirstParameter() - First) > Precision::PConfusion())
da72a17c 155 IsClosed = Standard_False; //trimmed curve differs
7fd59977 156
da72a17c 157 if ((ii>1) || !IsClosed ) { // Trim C
7fd59977 158 Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(C,First, Last);
159 C = TC;
160 }
0d969553 161 // otherwise preserve the integrity of the curve
7fd59977 162 if (TheLaw.IsNull()) {
163 myLaws->ChangeValue(ii) = new GeomFill_UniformSection(C);
164 }
165 else {
166 myLaws->ChangeValue(ii) = new GeomFill_EvolvedSection(C, TheLaw);
167 }
168 }
169 ii++;
170 }
171 }
172 }
173
174// cout << "new law" << endl;
175
0d969553 176 // Is the law closed by U ?
7fd59977 177 uclosed = W.Closed();
178 if (!uclosed) {
0d969553 179 // if not sure about the flag, make check
7fd59977 180 TopoDS_Edge Edge1, Edge2;
181 TopoDS_Vertex V1,V2;
182 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
183 Edge2 = TopoDS::Edge (myEdges->Value(1));
184
185 if( Edge1.Orientation() == TopAbs_REVERSED) {
186 V1 = TopExp::FirstVertex(Edge1);
187 }
188 else {
189 V1 = TopExp::LastVertex(Edge1);
190 }
191
192 if ( Edge2.Orientation() == TopAbs_REVERSED) {
193 V2 = TopExp::LastVertex(Edge2);
194 }
195 else {
196 V2 = TopExp::FirstVertex(Edge2);
197 }
198 if (V1.IsSame(V2)) {
199 uclosed = Standard_True;
200 }
201 else {
202 BRepAdaptor_Curve Curve1(Edge1);
203 BRepAdaptor_Curve Curve2(Edge2);
204 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
205 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
206 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
207 BRep_Tool::Tolerance(V1);
208
209 uclosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
210 }
211 }
212}
213
214
215//=======================================================================
216//function : IsVertex
217//purpose :
218//=======================================================================
219 Standard_Boolean BRepFill_ShapeLaw::IsVertex() const
220{
221 return vertex;
222}
223
224//=======================================================================
225//function : IsConstant
226//purpose :
227//=======================================================================
228 Standard_Boolean BRepFill_ShapeLaw::IsConstant() const
229{
230 return TheLaw.IsNull();
231}
232
233//=======================================================================
234//function : Vertex
235//purpose :
236//=======================================================================
237 TopoDS_Vertex
238 BRepFill_ShapeLaw::Vertex(const Standard_Integer Index,
239 const Standard_Real Param) const
240{
241 TopoDS_Edge E;
242 TopoDS_Vertex V;
243 if (Index <= myEdges->Length()) {
244 E = TopoDS::Edge(myEdges->Value(Index));
245 if (E.Orientation() == TopAbs_REVERSED)
246 V = TopExp::LastVertex(E);
247 else V = TopExp::FirstVertex(E);
248 }
249 else if (Index == myEdges->Length()+1) {
250 E = TopoDS::Edge(myEdges->Value(Index-1));
251 if (E.Orientation() == TopAbs_REVERSED)
252 V = TopExp::FirstVertex(E);
253 else V = TopExp::LastVertex(E);
254 }
255
256 if (!TheLaw.IsNull()) {
257 gp_Trsf T;
258 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(Param));
c8ea5b8e 259 //TopLoc_Location L(T);
260 //V.Move(L);
261 V = TopoDS::Vertex(BRepBuilderAPI_Transform(V, T));
7fd59977 262 }
263 return V;
264}
265
266
267///=======================================================================
268//function : VertexTol
0d969553 269//purpose : Evaluate the hole between 2 edges of the section
7fd59977 270//=======================================================================
271 Standard_Real BRepFill_ShapeLaw::VertexTol(const Standard_Integer Index,
272 const Standard_Real Param) const
273{
274 Standard_Real Tol = Precision::Confusion();
275 Standard_Integer I1, I2;
276 if ( (Index==0) || (Index==myEdges->Length()) ) {
0d969553 277 if (!uclosed) return Tol; //The least possible error
7fd59977 278 I1 = myEdges->Length();
279 I2 = 1;
280 }
281 else {
282 I1 = Index;
283 I2 = I1 +1;
284 }
285
286 Handle(GeomFill_SectionLaw) Loi;
287 Standard_Integer NbPoles, NbKnots, Degree;
288 Handle(TColgp_HArray1OfPnt) Poles;
289 Handle(TColStd_HArray1OfReal) Knots, Weigth;
290 Handle(TColStd_HArray1OfInteger) Mults;
291 Handle(Geom_BSplineCurve) BS;
292 gp_Pnt PFirst;
293
294 Loi = myLaws->Value(I1);
295 Loi->SectionShape( NbPoles, NbKnots, Degree);
296 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
297 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
298 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
299 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
300 Loi->Knots(Knots->ChangeArray1());
301 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
302 Loi->Mults(Mults->ChangeArray1());
303 BS = new (Geom_BSplineCurve) (Poles->Array1(),
304 Weigth->Array1(),
305 Knots->Array1(),
306 Mults->Array1(),
307 Degree,
308 Loi->IsUPeriodic());
309 PFirst = BS->Value( Knots->Value(Knots->Length()) );
310
311 Loi = myLaws->Value(I2);
312 Loi->SectionShape( NbPoles, NbKnots, Degree);
313 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
314 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
315 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
316 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
317 Loi->Knots(Knots->ChangeArray1());
318 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
319 Loi->Mults(Mults->ChangeArray1());
320 BS = new (Geom_BSplineCurve) (Poles->Array1(),
321 Weigth->Array1(),
322 Knots->Array1(),
323 Mults->Array1(),
324 Degree,
325 Loi->IsUPeriodic());
326 Tol += PFirst.Distance(BS->Value( Knots->Value(1)));
327 return Tol;
328}
329
330//=======================================================================
331//function : ConcatenedLaw
332//purpose :
333//=======================================================================
334
335 Handle(GeomFill_SectionLaw) BRepFill_ShapeLaw::ConcatenedLaw() const
336{
337 Handle(GeomFill_SectionLaw) Law;
338 if (myLaws->Length() == 1)
339 return myLaws->Value(1);
340 else {
341 TopoDS_Wire W;
342 TopoDS_Vertex V;
343 W = TopoDS::Wire(myShape);
344 if(!W.IsNull()) {
0d969553 345 // Concatenation of edges
7fd59977 346 Standard_Integer ii;
347 Standard_Real epsV, f, l;
348 Standard_Boolean Bof;
349 Handle(Geom_Curve) Composite;
350 Handle(Geom_TrimmedCurve) TC;
351 Composite = BRep_Tool::Curve(Edge(1), f, l);
352 TC = new (Geom_TrimmedCurve)(Composite, f, l);
353 GeomConvert_CompCurveToBSplineCurve Concat(TC);
354
355 for (ii=2, Bof=Standard_True; ii<=myEdges->Length() && Bof; ii++){
356 Composite = BRep_Tool::Curve(Edge(ii),f, l);
357 TC = new (Geom_TrimmedCurve)(Composite, f, l);
358 Bof = TopExp::CommonVertex(Edge(ii-1), Edge(ii), V);
359 if (Bof) {epsV = BRep_Tool::Tolerance(V);}
360 else epsV = 10*Precision::PConfusion();
361 Bof = Concat.Add(TC, epsV, Standard_True,
362 Standard_False, 20);
363 if (!Bof) Bof = Concat.Add(TC, 200*epsV,
364 Standard_True, Standard_False, 20);
0797d9d3 365#ifdef OCCT_DEBUG
7fd59977 366 if (!Bof)
367 cout << "BRepFill_ShapeLaw::ConcatenedLaw INCOMPLET !!!"
368 << endl;
369#endif
370 }
371 Composite = Concat.BSplineCurve();
372
373 if (TheLaw.IsNull()) {
374 Law = new (GeomFill_UniformSection)(Composite);
375 }
376 else {
377 Law = new (GeomFill_EvolvedSection)(Composite, TheLaw);
378 }
379 }
380 }
381 return Law;
382}
383
384//=======================================================================
385//function : Continuity
386//purpose :
387//=======================================================================
388 GeomAbs_Shape BRepFill_ShapeLaw::Continuity(const Standard_Integer Index,
389 const Standard_Real TolAngular) const
390{
391
c8ea5b8e 392 TopoDS_Edge Edge1, Edge2;
7fd59977 393 if ( (Index==0) || (Index==myEdges->Length()) ) {
0d969553 394 if (!uclosed) return GeomAbs_C0; //The least possible error
c8ea5b8e 395
7fd59977 396 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length()));
397 Edge2 = TopoDS::Edge (myEdges->Value(1));
398 }
399 else {
400 Edge1 = TopoDS::Edge (myEdges->Value(Index));
401 Edge2 = TopoDS::Edge (myEdges->Value(Index+1));
402 }
c8ea5b8e 403
404 TopoDS_Vertex V1,V2; //common vertex
405 TopoDS_Vertex vv1, vv2, vv3, vv4;
406 TopExp::Vertices(Edge1, vv1, vv2);
407 TopExp::Vertices(Edge2, vv3, vv4);
408 if (vv1.IsSame(vv3))
409 { V1 = vv1; V2 = vv3; }
410 else if (vv1.IsSame(vv4))
411 { V1 = vv1; V2 = vv4; }
412 else if (vv2.IsSame(vv3))
413 { V1 = vv2; V2 = vv3; }
414 else
415 { V1 = vv2; V2 = vv4; }
7fd59977 416
417 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
418 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
419 BRepAdaptor_Curve Curve1(Edge1);
420 BRepAdaptor_Curve Curve2(Edge2);
421 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
422 BRep_Tool::Tolerance(V1);
423 GeomAbs_Shape cont;
424 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular);
425
426 return cont;
427}
428
429//=======================================================================
430//function : D0
431//purpose :
432//=======================================================================
433 void BRepFill_ShapeLaw::D0(const Standard_Real U, TopoDS_Shape& S)
434{
435 S = myShape;
436 if (!TheLaw.IsNull()) {
437 gp_Trsf T;
438 T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(U));
c8ea5b8e 439 //TopLoc_Location L(T);
440 //S.Move(L);
441 S = BRepBuilderAPI_Transform(S, T);
7fd59977 442 }
443}