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