0022627: Change OCCT memory management defaults
[occt.git] / src / HLRTopoBRep / HLRTopoBRep_DSFiller.cxx
CommitLineData
7fd59977 1// File: HLRTopoBRep_DSFiller.cxx
2// Created: Tue Aug 10 16:16:53 1993
3// Author: Christophe MARION
4// <cma@ecolox>
5
6#include <HLRTopoBRep_DSFiller.ixx>
7
8#include <TopoDS.hxx>
9#include <TopExp.hxx>
10#include <TopExp_Explorer.hxx>
11#include <math_Vector.hxx>
12#include <TColgp_Array1OfPnt.hxx>
13#include <TColgp_Array1OfPnt2d.hxx>
14#include <TColStd_Array1OfReal.hxx>
15#include <TColStd_Array1OfInteger.hxx>
16#include <Geom_Line.hxx>
17#include <Geom_Circle.hxx>
18#include <Geom_Surface.hxx>
19#include <Geom_BSplineCurve.hxx>
20#include <GeomProjLib.hxx>
21#include <Geom2d_Curve.hxx>
22#include <Geom2d_BSplineCurve.hxx>
23#include <AppDef_BSplineCompute.hxx>
24#include <AppDef_MultiLine.hxx>
25#include <AppDef_MultiPointConstraint.hxx>
26#include <AppParCurves_MultiBSpCurve.hxx>
27#include <HLRTopoBRep_FaceIsoLiner.hxx>
28#include <BRep_Tool.hxx>
29#include <BRep_Builder.hxx>
30#include <BRepAdaptor_Curve.hxx>
31#include <BRepAdaptor_Curve2d.hxx>
32#include <BRepAdaptor_HCurve2d.hxx>
33#include <BRepTopAdaptor_HVertex.hxx>
34#include <BRepTopAdaptor_TopolTool.hxx>
35#include <BRepTopAdaptor_Tool.hxx>
36#include <Contap_TheLineOfContour.hxx>
37#include <Extrema_LocateExtPC.hxx>
38#include <Standard_ProgramError.hxx>
39#include <Precision.hxx>
40#include <BRepApprox_ApproxLine.hxx>
41#include <BRepApprox_Approx.hxx>
42
43#define INTERPOLATE 0
44#define BRISE 0
45#define APPROX 1
46
47//=======================================================================
48//function : Insert
49//purpose : explore the faces and insert them
50//=======================================================================
51
52void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
53 Contap_Contour& FO,
54 HLRTopoBRep_Data& DS,
55 BRepTopAdaptor_MapOfShapeTool& MST,
56 const Standard_Integer nbIso)
57{
58 TopTools_MapOfShape ShapeMap;
59 TopExp_Explorer ex(S,TopAbs_FACE);
60 DS.Clear();
61 Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0;
62 Standard_Integer f = 0;
63
64 while (ex.More()) {
65 if (ShapeMap.Add(ex.Current())) {
66 f++;
67 TopoDS_Face S1 = TopoDS::Face(ex.Current());
68 S1.Orientation(TopAbs_FORWARD);
69 Handle(BRepTopAdaptor_TopolTool) Domain;
70 Handle(Adaptor3d_HSurface) Surface;
71 if(MST.IsBound(S1)) {
72 BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1);
73 Domain = BRT.GetTopolTool();
74 Surface = BRT.GetSurface();
75 }
76 else {
77 BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion());
78 MST.Bind(S1,BRT);
79 Domain = BRT.GetTopolTool();
80 Surface = BRT.GetSurface();
81 }
82 FO.Perform(Surface,Domain);
83 if (FO.IsDone()) {
84 if (!FO.IsEmpty())
85 InsertFace(f,S1,FO,DS,withPCurve);
86 }
87 if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
88 }
89 ex.Next();
90 }
91 ProcessEdges(DS);
92}
93
94//=======================================================================
95//function : InsertFace
96//purpose : private, insert the outlines of a face
97//=======================================================================
98
99void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer FI,
100 const TopoDS_Face& F,
101 Contap_Contour& FO,
102 HLRTopoBRep_Data& DS,
103 const Standard_Boolean withPCurve)
104{
105 // Insert the intersections of FO in DS
106
5c953701 107 const Standard_Real tol = BRep_Tool::Tolerance(F);
7fd59977 108 TopTools_ListOfShape& IntL = DS.AddIntL(F);
109 TopTools_ListOfShape& OutL = DS.AddOutL(F);
5c953701 110
7fd59977 111 TopoDS_Vertex VF,VL;
5c953701 112 /*
113 TopTools_MapOfShape VM;
7fd59977 114 TopExp_Explorer ex(F,TopAbs_EDGE);
7fd59977 115 while (ex.More()) {
116 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
117 if (BRep_Tool::IsClosed(E,F)) {
118 TopExp::Vertices(E,VF,VL);
119 VM.Add(VF);
120 VM.Add(VL);
121 }
122 ex.Next();
123 }
5c953701 124 */
7fd59977 125
5c953701 126 const Standard_Integer NbLines = FO.NbLines();
127 Standard_Integer CurLine = 1;
128 for (; CurLine <= NbLines; CurLine++)
129 {
7fd59977 130 const Contap_TheLineOfContour& Line = FO.Line(CurLine);
5c953701 131 const Standard_Integer NbPoints = Line.NbVertex();
7fd59977 132 Standard_Integer CurPoint;
5c953701 133 if (Line.TypeContour() == Contap_Restriction)
134 {
7fd59977 135 // OutLine on restriction
5c953701 136 TopoDS_Edge E = (*(BRepAdaptor_Curve2d*)&(Line.Arc()->Curve2d())).Edge();
7fd59977 137 OutL.Append(E);
138 TopExp::Vertices(E,VF,VL);
139 // insert the Internal points.
140
141 for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
5c953701 142 Contap_ThePointOfContour P = Line.Vertex(CurPoint);
143 if (P.IsInternal()) {
144 if (P.Value().IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) {
145 if (P.Value().IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) {
146 InsertVertex(P,tol,E,DS);
147 }
148 }
149 }
7fd59977 150 }
151 }
5c953701 152 else
153 {
7fd59977 154 for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
7fd59977 155
5c953701 156 const Contap_ThePointOfContour PF = Line.Vertex(CurPoint);
157 if (PF.IsInternal() && CurPoint != 1)
158 VF = VL;
159 else
160 VF = MakeVertex(PF,tol,DS);
161 const Standard_Real parF = PF.ParameterOnLine();
7fd59977 162
5c953701 163 if (CurPoint < NbPoints) {
164 const Contap_ThePointOfContour PL = Line.Vertex(CurPoint+1);
165 VL = MakeVertex(PL,tol,DS);
166 const Standard_Real parL = PL.ParameterOnLine();
167
168 if( (parL-parF) > Precision::PConfusion() ) {
169
170 Handle(Geom_Curve) C;
171 Handle(Geom2d_Curve) C2d;
172 Standard_Real first = parF;
173 Standard_Real last = parL;
174 Standard_Boolean InsuffisantNumberOfPoints=Standard_False;
175
176 switch (Line.TypeContour()) {
7fd59977 177
5c953701 178 case Contap_Lin :
179 {
180 C = new Geom_Line(Line.Line());
181 if (withPCurve) {
182 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
183 Standard_Real Tol = 1e-7;
184 C2d = GeomProjLib::Curve2d(C,first,last,S,Tol);
185 }
186 }
187 break;
7fd59977 188
5c953701 189 case Contap_Circle :
190 {
191 C = new Geom_Circle(Line.Circle());
192 if (withPCurve) {
193 TopLoc_Location Loc;
194 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Loc);
195 if (!Loc.IsIdentity()) {
196 S = Handle(Geom_Surface)::DownCast(S->Transformed(Loc.Transformation()));
197 }
198 Standard_Real Tol = 1e-7;
199 C2d = GeomProjLib::Curve2d(C,first,last,S,Tol);
200 }
201 }
202 break;
7fd59977 203
5c953701 204 case Contap_Walking :
205 {
206 // copy the points
207 Standard_Integer ipF = Standard_Integer(parF);
208 Standard_Integer ipL = Standard_Integer(parL);
7fd59977 209
5c953701 210 if(ipL-ipF < 1) {
211 InsuffisantNumberOfPoints=Standard_True;
212 //cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<endl;
213 }
214/*
7fd59977 215 else if(ipL-ipF < 6) {
216 // compute the tangents
217 Contap_TheSurfFunctionOfContour& SFunc =
218 FO.SurfaceFunction();
219
220 Standard_Boolean isTg1,isTg2;
221 gp_Vec tg1,tg2;
222 gp_Vec2d uv1,uv2;
223 math_Vector UV(1,2),F(1,1);
224
225 Line.Point(ipF).ParametersOnS2(UV(1),UV(2));
226 SFunc.Value(UV,F);
227 isTg1 = SFunc.IsTangent();
228 if (!isTg1) {
229 tg1 = SFunc.Direction3d();
230 if (withPCurve) uv1 = SFunc.Direction2d();
231 }
232
233 Line.Point(ipL).ParametersOnS2(UV(1),UV(2));
234 SFunc.Value(UV,F);
235 isTg2 = SFunc.IsTangent();
236 if (!isTg2) {
237 tg2 = SFunc.Direction3d();
238 if (withPCurve) uv2 = SFunc.Direction2d();
239 }
240 // interpolate
241 Standard_Integer nbp = ipL - ipF + 1;
242 AppDef_MultiLine MLine(nbp);
243 Standard_Integer nb2d = 0;
244 if (withPCurve) nb2d = 1;
245
246 for (Standard_Integer i = 1; i <= nbp; i++) {
247 AppDef_MultiPointConstraint MP(1, nb2d);
248 MP.SetPoint(1,Line.Point(i + ipF - 1).Value());
249 if (withPCurve) {
250 Line.Point(i + ipF - 1).ParametersOnS2(UV(1),UV(2));
251 MP.SetPoint2d(2,gp_Pnt2d(UV(1),UV(2)));
252 }
253
254 if (i == 1 && !isTg1) {
255 MP.SetTang (1,tg1);
256 if (withPCurve) MP.SetTang2d(2,uv1);
257 }
258 if (i == nbp && !isTg2) {
259 MP.SetTang (1,tg2);
260 if (withPCurve) MP.SetTang2d(2,uv2);
261 }
262 MLine.SetValue(i,MP);
263 }
264 AppDef_BSplineCompute interp;
265 interp.Interpol(MLine);
266 AppParCurves_MultiBSpCurve TheCurve = interp.Value();
267 Standard_Integer Degree = TheCurve.Degree();
268 TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
269 TheCurve.Curve(1,Poles);
270 C = new Geom_BSplineCurve(Poles,
271 TheCurve.Knots(),
272 TheCurve.Multiplicities(),
273 Degree);
274 if (withPCurve) {
275 TColgp_Array1OfPnt2d Pol2d(1,TheCurve.NbPoles());
276 TheCurve.Curve(2,Pol2d);
277 C2d = new Geom2d_BSplineCurve(Pol2d,
278 TheCurve.Knots(),
279 TheCurve.Multiplicities(),
280 Degree);
281 }
282 first = 0;
283 last = 1;
284 }
5c953701 285*/
286 else if(ipL-ipF < 5) {
287 const Standard_Integer nbp = ipL - ipF + 1;
288 TColStd_Array1OfReal knots(1,nbp);
289 TColStd_Array1OfInteger mults(1,nbp);
290 TColgp_Array1OfPnt Points(1,nbp);
7fd59977 291
5c953701 292 for(Standard_Integer i=1;i<=nbp;i++) {
293 knots.SetValue(i,(Standard_Real)i);
294 mults.SetValue(i,1);
295 Points.SetValue(i,Line.Point(i+ipF-1).Value());
296 }
297 mults(1)=mults(nbp)=2;
298 C = new Geom_BSplineCurve(Points,knots,mults,1);
7fd59977 299
5c953701 300 if(withPCurve) {
301 TColgp_Array1OfPnt2d Points2d(1,nbp);
302 for(Standard_Integer i=1;i<=nbp;i++) {
303 Standard_Real u,v;
304 Line.Point(i+ipF-1).ParametersOnS2(u,v);
305 Points2d.SetValue(i,gp_Pnt2d(u,v));
306 }
307 C2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
308 }
309 first = 1;
310 last = nbp;
311 }
312 else {
313 const Standard_Integer nbp = ipL - ipF + 1;
314 TColStd_Array1OfReal knots(1,nbp);
315 TColStd_Array1OfInteger mults(1,nbp);
316 TColgp_Array1OfPnt Points(1,nbp);
317
318 Standard_Real Maxx,Maxy,Maxz,Maxu,Maxv;
319 Standard_Real Minx,Miny,Minz,Minu,Minv;
320 Maxx=Maxy=Maxz=Maxu=Maxv=-RealLast();
321 Minx=Miny=Minz=Minu=Minv=RealLast();
7fd59977 322
5c953701 323 for(Standard_Integer i=1;i<=nbp;i++) {
324 knots.SetValue(i,(Standard_Real)i);
325 mults.SetValue(i,1);
326 const gp_Pnt& P= Line.Point(i+ipF-1).Value();
327 if(P.X()<Minx) Minx=P.X();
328 if(P.Y()<Miny) Miny=P.Y();
329 if(P.Z()<Minz) Minz=P.Z();
330 if(P.X()>Maxx) Maxx=P.X();
331 if(P.Y()>Maxy) Maxy=P.Y();
332 if(P.Z()>Maxz) Maxz=P.Z();
333 Points.SetValue(i,P);
334 }
335 mults(1)=mults(nbp)=2;
336 Handle(Geom_BSplineCurve) AppC;
337 Handle(Geom2d_BSplineCurve) AppC2d;
338 AppC = new Geom_BSplineCurve(Points,knots,mults,1);
339
340 if(withPCurve) {
341 TColgp_Array1OfPnt2d Points2d(1,nbp);
342 for(Standard_Integer i=1;i<=nbp;i++) {
343 Standard_Real u,v;
344 Line.Point(i+ipF-1).ParametersOnS2(u,v);
345 if(u<Minu) Minu=u;
346 if(v<Minv) Minv=v;
347 if(u>Maxu) Maxu=u;
348 if(v>Maxv) Maxv=v;
349 Points2d.SetValue(i,gp_Pnt2d(u,v));
350 }
351 AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
352 }
353 first = 1;
354 last = nbp;
7fd59977 355
5c953701 356 Handle(BRepApprox_ApproxLine) AppLine;
357 Handle(Geom2d_BSplineCurve) CNull;
358 AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
7fd59977 359
5c953701 360 Standard_Integer dmin=4,dmax=8,niter=0;
361 Standard_Boolean tg= Standard_False;
362 BRepApprox_Approx Approx;
363 Standard_Real TOL3d,TOL2d,TOL=0.0001;
7fd59977 364
5c953701 365 Maxx-=Minx; Maxy-=Miny; Maxz-=Minz;
366 Maxu-=Minu; Maxv-=Minv;
367 if(Maxy>Maxx) Maxx=Maxy;
368 if(Maxz>Maxx) Maxx=Maxy;
369 if(Maxv>Maxu) Maxu=Maxv;
7fd59977 370
5c953701 371 TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
372 TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
7fd59977 373
5c953701 374 //-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<endl;
7fd59977 375
5c953701 376 Approx.SetParameters(TOL3d,TOL2d,dmin,dmax,niter,tg);
377 Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
378 if (!Approx.IsDone()) {
379 C = AppC;
380 C2d=AppC2d;
381 first = 1;
382 last = nbp;
383 }
384 else {
385 const AppParCurves_MultiBSpCurve& AppVal = Approx.Value(1);
386 TColgp_Array1OfPnt poles3d(1,AppVal.NbPoles());
387 AppVal.Curve(1,poles3d);
388 C = new Geom_BSplineCurve(poles3d,AppVal.Knots(),AppVal.Multiplicities(),AppVal.Degree());
7fd59977 389
5c953701 390 const AppParCurves_MultiBSpCurve& AppVal2 = Approx.Value(2);
391 TColgp_Array1OfPnt2d poles2d(1,AppVal2.NbPoles());
392 AppVal2.Curve(2,poles2d);
393 C2d = new Geom2d_BSplineCurve(poles2d,AppVal2.Knots(),AppVal2.Multiplicities(),AppVal2.Degree());
394 first = C2d->FirstParameter();
395 last = C2d->LastParameter();
396 }
397 }
398 }
399 break;
7fd59977 400
5c953701 401 case Contap_Restriction :
402 {
403 Standard_ProgramError::Raise("HLRTopoBRep_DSFiller::InsertFace : Restriction");
404 }
405 break;
406 }
7fd59977 407
5c953701 408 // compute the PCurve
409 // make the edge
410 if (!InsuffisantNumberOfPoints) {
411 TopoDS_Edge E;
412 BRep_Builder B;
413 B.MakeEdge(E,C,tol);
414 VF.Orientation(TopAbs_FORWARD);
415 VL.Orientation(TopAbs_REVERSED);
416 B.Add(E,VF);
417 B.Add(E,VL);
418 B.Range(E,first,last);
419
420 if (!C2d.IsNull()) {
421 BRep_Builder B;
422 B.UpdateEdge(E,C2d,F,BRep_Tool::Tolerance(F));
423 }
7fd59977 424
5c953701 425 // add the edge in the DS
426 if (!E.IsNull())
427 IntL.Append(E);
428 }
429 }
430 }
7fd59977 431 }
432 }
433 }
434}
435
436//=======================================================================
437//function : MakeVertex
438//purpose : private, make a vertex from an intersection point
439//=======================================================================
440
441TopoDS_Vertex
442HLRTopoBRep_DSFiller::MakeVertex (const Contap_ThePointOfContour& P,
443 const Standard_Real tol,
444 HLRTopoBRep_Data& DS)
445{
446 BRep_Builder B;
447 TopoDS_Vertex V;
448 if (P.IsVertex()) {
449 V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
450 DS.AddOutV(V);
451 }
452 else {
453 // if on arc, insert in the DS
454 if (P.IsOnArc()) {
455 const TopoDS_Edge& E =
456 (*(BRepAdaptor_Curve2d*)&((P.Arc())->Curve2d())).Edge();
457 Standard_Real Par = P.ParameterOnArc();
458 const gp_Pnt& P3d = P.Value();
459
460 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
461 TopoDS_Vertex curV = DS.Vertex();
462 Standard_Real curP = DS.Parameter();
463 const gp_Pnt& PPP=BRep_Tool::Pnt(curV);
464 Standard_Real TTT=BRep_Tool::Tolerance(curV);
465 if (P3d.IsEqual(PPP,TTT)) {
466 V = curV;
467 break;
468 }
469 else if (Par < curP) {
470 B.MakeVertex(V,P.Value(),tol);
471 DS.InsertBefore(V,Par);
472 break;
473 }
474 }
475 if (!DS.MoreVertex()) {
476 B.MakeVertex(V,P.Value(),tol);
477 DS.Append(V,Par);
478 }
479 DS.AddOutV(V);
480 }
481 // if internal create a vertex and insert in the DS
482 else {
483 B.MakeVertex(V,P.Value(),tol);
484 if (P.IsInternal())
485 DS.AddIntV(V);
486 else
487 DS.AddOutV(V);
488 }
489 }
490 return V;
491}
492
493//=======================================================================
494//function : InsertVertex
495//purpose : private, insert a vertex from an internal intersection point
496// on resctriction
497//=======================================================================
498
499void
500HLRTopoBRep_DSFiller::InsertVertex (const Contap_ThePointOfContour& P,
501 const Standard_Real tol,
502 const TopoDS_Edge& E,
503 HLRTopoBRep_Data& DS)
504{
505 BRep_Builder B;
506 TopoDS_Vertex V;
507
508 if (P.IsVertex()) {
509 V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
510 }
511 else {
512 Standard_Real Par = P.ParameterOnLine();
513
514 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
515 TopoDS_Vertex curV = DS.Vertex();
516 Standard_Real curP = DS.Parameter();
517 if (P.Value().IsEqual(BRep_Tool::Pnt(curV),
518 BRep_Tool::Tolerance(curV))) {
519 V = curV;
520 break;
521 }
522 else if (Par < curP) {
523 B.MakeVertex(V,P.Value(),tol);
524 DS.InsertBefore(V,Par);
525 break;
526 }
527 }
528 if (!DS.MoreVertex()) {
529 B.MakeVertex(V,P.Value(),tol);
530 DS.Append(V,Par);
531 }
532 }
533 DS.AddIntV(V);
534}
535
536//=======================================================================
537//function : ProcessEdges
538//purpose : private, split edges with outline vertices
539//=======================================================================
540
541void HLRTopoBRep_DSFiller::ProcessEdges (HLRTopoBRep_Data& DS)
542{
543 BRep_Builder B;
544 TopoDS_Edge newE;
545 TopoDS_Vertex VF,VL,VI;
546 Standard_Real PF,PL,PI;
547
548 for (DS.InitEdge(); DS.MoreEdge(); DS.NextEdge()) {
549 TopoDS_Edge E = DS.Edge();
550 TopTools_ListOfShape& SplE = DS.AddSplE(E);
551 VF = TopExp::FirstVertex(E);
552 VL = TopExp::LastVertex(E);
553 BRep_Tool::Range(E,PF,PL);
554 VF.Orientation(TopAbs_FORWARD);
555 VL.Orientation(TopAbs_REVERSED);
556
557 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
558 VI = DS.Vertex();
559 PI = DS.Parameter();
560 VI.Orientation(TopAbs_REVERSED);
561 newE = E;
562 newE.EmptyCopy();
563 newE.Orientation(TopAbs_FORWARD);
564 B.Add(newE,VF);
565 B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
566 B.Add(newE,VI);
567 B.UpdateVertex(VI,PI,newE,BRep_Tool::Tolerance(VI));
568 newE.Orientation(E.Orientation());
569 SplE.Append(newE);
570 VF = VI;
571 PF = PI;
572 VF.Orientation(TopAbs_FORWARD);
573 }
574 newE = E;
575 newE.EmptyCopy();
576 newE.Orientation(TopAbs_FORWARD);
577 B.Add(newE,VF);
578 B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
579 B.Add(newE,VL);
580 B.UpdateVertex(VL,PL,newE,BRep_Tool::Tolerance(VL));
581 newE.Orientation(E.Orientation());
582 SplE.Append(newE);
583 }
584}
585