1 // Created on: 1993-08-10
2 // Created by: Christophe MARION
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <HLRTopoBRep_DSFiller.ixx>
21 #include <TopExp_Explorer.hxx>
22 #include <math_Vector.hxx>
23 #include <TColgp_Array1OfPnt.hxx>
24 #include <TColgp_Array1OfPnt2d.hxx>
25 #include <TColStd_Array1OfReal.hxx>
26 #include <TColStd_Array1OfInteger.hxx>
27 #include <Geom_Line.hxx>
28 #include <Geom_Circle.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <GeomProjLib.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_BSplineCurve.hxx>
34 #include <AppDef_BSplineCompute.hxx>
35 #include <AppDef_MultiLine.hxx>
36 #include <AppDef_MultiPointConstraint.hxx>
37 #include <AppParCurves_MultiBSpCurve.hxx>
38 #include <HLRTopoBRep_FaceIsoLiner.hxx>
39 #include <BRep_Tool.hxx>
40 #include <BRep_Builder.hxx>
41 #include <BRepAdaptor_Curve.hxx>
42 #include <BRepAdaptor_Curve2d.hxx>
43 #include <BRepAdaptor_HCurve2d.hxx>
44 #include <BRepTopAdaptor_HVertex.hxx>
45 #include <BRepTopAdaptor_TopolTool.hxx>
46 #include <BRepTopAdaptor_Tool.hxx>
47 #include <Contap_Line.hxx>
48 #include <Extrema_LocateExtPC.hxx>
49 #include <Standard_ProgramError.hxx>
50 #include <Precision.hxx>
51 #include <BRepApprox_ApproxLine.hxx>
52 #include <BRepApprox_Approx.hxx>
53 #include <BRep_TEdge.hxx>
54 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
55 #include <BRep_CurveRepresentation.hxx>
56 #include <BRepExtrema_ExtPC.hxx>
57 #include <TopTools_ListIteratorOfListOfShape.hxx>
64 static Standard_Boolean IntLineRisesFromRegularity(const TopoDS_Edge& anIntLine,
65 const TopoDS_Edge& anEdge,
67 const TopTools_ListOfShape& aList)
69 TopoDS_Vertex Ver [2];
70 TopExp::Vertices(anIntLine, Ver[0], Ver[1]);
72 //find min param and max param
73 Standard_Real MinPar = RealLast(), MaxPar = RealFirst();
74 TopTools_ListIteratorOfListOfShape itl(aList);
75 for (; itl.More(); itl.Next())
77 const TopoDS_Edge& anOutLine = TopoDS::Edge(itl.Value());
78 Standard_Real aFirst, aLast;
79 BRep_Tool::Range(anOutLine, aFirst, aLast);
86 Standard_Real theTol = BRep_Tool::Tolerance(anEdge);
87 Standard_Real ParamTol = Precision::Confusion();
89 Standard_Integer i, j;
90 for (i = 0; i < 2; i++)
92 BRepExtrema_ExtPC anExtPC(Ver[i], anEdge);
93 if (!anExtPC.IsDone())
95 Standard_Integer NbExt = anExtPC.NbExt();
98 Standard_Integer jmin = 1;
99 for (j = 2; j <= NbExt; j++)
100 if (anExtPC.SquareDistance(j) < anExtPC.SquareDistance(jmin))
102 Standard_Real aDist = anExtPC.SquareDistance(jmin);
107 Standard_Real theParam = anExtPC.Parameter(jmin);
108 if (theParam > MinPar + ParamTol &&
109 theParam < MaxPar - ParamTol)
110 return Standard_True;
113 return Standard_False;
117 //=======================================================================
119 //purpose : explore the faces and insert them
120 //=======================================================================
122 void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
124 HLRTopoBRep_Data& DS,
125 BRepTopAdaptor_MapOfShapeTool& MST,
126 const Standard_Integer nbIso)
128 TopTools_MapOfShape ShapeMap;
129 TopExp_Explorer ex(S,TopAbs_FACE);
131 Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0;
132 Standard_Integer f = 0;
135 if (ShapeMap.Add(ex.Current())) {
137 TopoDS_Face S1 = TopoDS::Face(ex.Current());
138 S1.Orientation(TopAbs_FORWARD);
139 Handle(BRepTopAdaptor_TopolTool) Domain;
140 Handle(Adaptor3d_HSurface) Surface;
141 if(MST.IsBound(S1)) {
142 BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1);
143 Domain = BRT.GetTopolTool();
144 Surface = BRT.GetSurface();
147 BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion());
149 Domain = BRT.GetTopolTool();
150 Surface = BRT.GetSurface();
152 FO.Perform(Surface, Domain);
155 InsertFace(f,S1,FO,DS,withPCurve);
157 if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
164 //=======================================================================
165 //function : InsertFace
166 //purpose : private, insert the outlines of a face
167 //=======================================================================
169 void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
170 const TopoDS_Face& F,
172 HLRTopoBRep_Data& DS,
173 const Standard_Boolean withPCurve)
175 // Insert the intersections of FO in DS
177 const Standard_Real tol = BRep_Tool::Tolerance(F);
178 TopTools_ListOfShape& IntL = DS.AddIntL(F);
179 TopTools_ListOfShape& OutL = DS.AddOutL(F);
183 TopTools_MapOfShape VM;
184 TopExp_Explorer ex(F,TopAbs_EDGE);
186 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
187 if (BRep_Tool::IsClosed(E,F)) {
188 TopExp::Vertices(E,VF,VL);
196 const Standard_Integer NbLines = FO.NbLines();
197 Standard_Integer CurLine;
198 for (CurLine = 1; CurLine <= NbLines; CurLine++)
200 const Contap_Line& Line = FO.Line(CurLine);
201 const Standard_Integer NbPoints = Line.NbVertex();
202 Standard_Integer CurPoint;
203 if (Line.TypeContour() == Contap_Restriction)
205 // OutLine on restriction
206 TopoDS_Edge E = (*(BRepAdaptor_Curve2d*)&(Line.Arc()->Curve2d())).Edge();
208 TopExp::Vertices(E,VF,VL);
209 // insert the Internal points.
211 for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
212 Contap_Point P = Line.Vertex(CurPoint);
213 if (P.IsInternal()) {
214 if (P.Value().IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) {
215 if (P.Value().IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) {
216 InsertVertex(P,tol,E,DS);
224 for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
226 const Contap_Point PF = Line.Vertex(CurPoint);
227 if (PF.IsInternal() && CurPoint != 1)
230 VF = MakeVertex(PF,tol,DS);
231 const Standard_Real parF = PF.ParameterOnLine();
233 if (CurPoint < NbPoints) {
234 const Contap_Point PL = Line.Vertex(CurPoint+1);
235 VL = MakeVertex(PL,tol,DS);
236 const Standard_Real parL = PL.ParameterOnLine();
238 if( (parL-parF) > Precision::PConfusion() ) {
240 Handle(Geom_Curve) C;
241 Handle(Geom2d_Curve) C2d;
242 Standard_Real first = parF;
243 Standard_Real last = parL;
244 Standard_Boolean InsuffisantNumberOfPoints=Standard_False;
246 switch (Line.TypeContour()) {
250 C = new Geom_Line(Line.Line());
252 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
253 Standard_Real Tol = 1e-7;
254 C2d = GeomProjLib::Curve2d(C,first,last,S,Tol);
261 C = new Geom_Circle(Line.Circle());
264 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Loc);
265 if (!Loc.IsIdentity()) {
266 S = Handle(Geom_Surface)::DownCast(S->Transformed(Loc.Transformation()));
268 Standard_Real Tol = 1e-7;
269 C2d = GeomProjLib::Curve2d(C,first,last,S,Tol);
274 case Contap_Walking :
277 Standard_Integer ipF = Standard_Integer(parF);
278 Standard_Integer ipL = Standard_Integer(parL);
281 InsuffisantNumberOfPoints=Standard_True;
282 //cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<endl;
285 else if(ipL-ipF < 6) {
286 // compute the tangents
287 Contap_SurfFunction& SFunc =
288 FO.SurfaceFunction();
290 Standard_Boolean isTg1,isTg2;
293 math_Vector UV(1,2),F(1,1);
295 Line.Point(ipF).ParametersOnS2(UV(1),UV(2));
297 isTg1 = SFunc.IsTangent();
299 tg1 = SFunc.Direction3d();
300 if (withPCurve) uv1 = SFunc.Direction2d();
303 Line.Point(ipL).ParametersOnS2(UV(1),UV(2));
305 isTg2 = SFunc.IsTangent();
307 tg2 = SFunc.Direction3d();
308 if (withPCurve) uv2 = SFunc.Direction2d();
311 Standard_Integer nbp = ipL - ipF + 1;
312 AppDef_MultiLine MLine(nbp);
313 Standard_Integer nb2d = 0;
314 if (withPCurve) nb2d = 1;
316 for (Standard_Integer i = 1; i <= nbp; i++) {
317 AppDef_MultiPointConstraint MP(1, nb2d);
318 MP.SetPoint(1,Line.Point(i + ipF - 1).Value());
320 Line.Point(i + ipF - 1).ParametersOnS2(UV(1),UV(2));
321 MP.SetPoint2d(2,gp_Pnt2d(UV(1),UV(2)));
324 if (i == 1 && !isTg1) {
326 if (withPCurve) MP.SetTang2d(2,uv1);
328 if (i == nbp && !isTg2) {
330 if (withPCurve) MP.SetTang2d(2,uv2);
332 MLine.SetValue(i,MP);
334 AppDef_BSplineCompute interp;
335 interp.Interpol(MLine);
336 AppParCurves_MultiBSpCurve TheCurve = interp.Value();
337 Standard_Integer Degree = TheCurve.Degree();
338 TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
339 TheCurve.Curve(1,Poles);
340 C = new Geom_BSplineCurve(Poles,
342 TheCurve.Multiplicities(),
345 TColgp_Array1OfPnt2d Pol2d(1,TheCurve.NbPoles());
346 TheCurve.Curve(2,Pol2d);
347 C2d = new Geom2d_BSplineCurve(Pol2d,
349 TheCurve.Multiplicities(),
356 else if(ipL-ipF < 5) {
357 const Standard_Integer nbp = ipL - ipF + 1;
358 TColStd_Array1OfReal knots(1,nbp);
359 TColStd_Array1OfInteger mults(1,nbp);
360 TColgp_Array1OfPnt Points(1,nbp);
362 for(Standard_Integer i=1;i<=nbp;i++) {
363 knots.SetValue(i,(Standard_Real)i);
365 Points.SetValue(i,Line.Point(i+ipF-1).Value());
367 mults(1)=mults(nbp)=2;
368 C = new Geom_BSplineCurve(Points,knots,mults,1);
371 TColgp_Array1OfPnt2d Points2d(1,nbp);
372 for(Standard_Integer i=1;i<=nbp;i++) {
374 Line.Point(i+ipF-1).ParametersOnS2(u,v);
375 Points2d.SetValue(i,gp_Pnt2d(u,v));
377 C2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
383 const Standard_Integer nbp = ipL - ipF + 1;
384 TColStd_Array1OfReal knots(1,nbp);
385 TColStd_Array1OfInteger mults(1,nbp);
386 TColgp_Array1OfPnt Points(1,nbp);
388 Standard_Real Maxx,Maxy,Maxz,Maxu,Maxv;
389 Standard_Real Minx,Miny,Minz,Minu,Minv;
390 Maxx=Maxy=Maxz=Maxu=Maxv=-RealLast();
391 Minx=Miny=Minz=Minu=Minv=RealLast();
393 for(Standard_Integer i=1;i<=nbp;i++) {
394 knots.SetValue(i,(Standard_Real)i);
396 const gp_Pnt& P= Line.Point(i+ipF-1).Value();
397 if(P.X()<Minx) Minx=P.X();
398 if(P.Y()<Miny) Miny=P.Y();
399 if(P.Z()<Minz) Minz=P.Z();
400 if(P.X()>Maxx) Maxx=P.X();
401 if(P.Y()>Maxy) Maxy=P.Y();
402 if(P.Z()>Maxz) Maxz=P.Z();
403 Points.SetValue(i,P);
405 mults(1)=mults(nbp)=2;
406 Handle(Geom_BSplineCurve) AppC;
407 Handle(Geom2d_BSplineCurve) AppC2d;
408 AppC = new Geom_BSplineCurve(Points,knots,mults,1);
411 TColgp_Array1OfPnt2d Points2d(1,nbp);
412 for(Standard_Integer i=1;i<=nbp;i++) {
414 Line.Point(i+ipF-1).ParametersOnS2(u,v);
419 Points2d.SetValue(i,gp_Pnt2d(u,v));
421 AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
426 Handle(BRepApprox_ApproxLine) AppLine;
427 Handle(Geom2d_BSplineCurve) CNull;
428 AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
430 Standard_Integer dmin=4,dmax=8,niter=0;
431 Standard_Boolean tg= Standard_False;
432 BRepApprox_Approx Approx;
433 Standard_Real TOL3d,TOL2d,TOL=0.0001;
435 Maxx-=Minx; Maxy-=Miny; Maxz-=Minz;
436 Maxu-=Minu; Maxv-=Minv;
437 if(Maxy>Maxx) Maxx=Maxy;
438 if(Maxz>Maxx) Maxx=Maxy;
439 if(Maxv>Maxu) Maxu=Maxv;
441 TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
442 TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
444 //-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<endl;
446 Approx.SetParameters(TOL3d,TOL2d,dmin,dmax,niter,tg);
447 Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
448 if (!Approx.IsDone()) {
455 const AppParCurves_MultiBSpCurve& AppVal = Approx.Value(1);
456 TColgp_Array1OfPnt poles3d(1,AppVal.NbPoles());
457 AppVal.Curve(1,poles3d);
458 C = new Geom_BSplineCurve(poles3d,AppVal.Knots(),AppVal.Multiplicities(),AppVal.Degree());
460 const AppParCurves_MultiBSpCurve& AppVal2 = Approx.Value(2);
461 TColgp_Array1OfPnt2d poles2d(1,AppVal2.NbPoles());
462 AppVal2.Curve(2,poles2d);
463 C2d = new Geom2d_BSplineCurve(poles2d,AppVal2.Knots(),AppVal2.Multiplicities(),AppVal2.Degree());
464 first = C2d->FirstParameter();
465 last = C2d->LastParameter();
471 case Contap_Restriction :
473 Standard_ProgramError::Raise("HLRTopoBRep_DSFiller::InsertFace : Restriction");
478 // compute the PCurve
480 if (!InsuffisantNumberOfPoints) {
484 VF.Orientation(TopAbs_FORWARD);
485 VL.Orientation(TopAbs_REVERSED);
488 B.Range(E,first,last);
492 B.UpdateEdge(E,C2d,F,BRep_Tool::Tolerance(F));
495 // add the edge in the DS
505 //jgv: correction of internal outlines: remove those that rise from middle of boundary outlines
506 TopTools_ListIteratorOfListOfShape itl(IntL);
509 TopoDS_Edge anIntLine = TopoDS::Edge(itl.Value());
510 Standard_Real found = Standard_False;
511 TopExp_Explorer Explo(F, TopAbs_EDGE);
512 for (; Explo.More(); Explo.Next())
514 TopoDS_Edge anEdge = TopoDS::Edge(Explo.Current());
515 if (!BRep_Tool::HasContinuity(anEdge))
518 TopLoc_Location RegLoc;
519 Standard_Real fpar, lpar;
520 Handle(Geom_Curve) RegCurve = BRep_Tool::Curve(anEdge, RegLoc, fpar, lpar);
521 TopTools_ListOfShape thelist;
522 TopTools_ListIteratorOfListOfShape itoutl(OutL);
523 for (; itoutl.More(); itoutl.Next())
525 TopoDS_Edge anOutLine = TopoDS::Edge(itoutl.Value());
526 TopLoc_Location aLoc;
527 Standard_Real aFirst, aLast;
528 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anOutLine, aLoc, aFirst, aLast);
529 if (aCurve == RegCurve && aLoc == RegLoc)
530 thelist.Append(anOutLine);
533 if (thelist.IsEmpty())
536 if (IntLineRisesFromRegularity(anIntLine, anEdge, F, thelist))
539 found = Standard_True;
547 ///////////////////////////////////////////////////
550 //=======================================================================
551 //function : MakeVertex
552 //purpose : private, make a vertex from an intersection point
553 //=======================================================================
556 HLRTopoBRep_DSFiller::MakeVertex (const Contap_Point& P,
557 const Standard_Real tol,
558 HLRTopoBRep_Data& DS)
563 V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
567 // if on arc, insert in the DS
569 const TopoDS_Edge& E =
570 (*(BRepAdaptor_Curve2d*)&((P.Arc())->Curve2d())).Edge();
571 Standard_Real Par = P.ParameterOnArc();
572 const gp_Pnt& P3d = P.Value();
574 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
575 TopoDS_Vertex curV = DS.Vertex();
576 Standard_Real curP = DS.Parameter();
577 const gp_Pnt& PPP=BRep_Tool::Pnt(curV);
578 Standard_Real TTT=BRep_Tool::Tolerance(curV);
579 if (P3d.IsEqual(PPP,TTT)) {
583 else if (Par < curP) {
584 B.MakeVertex(V,P.Value(),tol);
585 DS.InsertBefore(V,Par);
589 if (!DS.MoreVertex()) {
590 B.MakeVertex(V,P.Value(),tol);
595 // if internal create a vertex and insert in the DS
597 B.MakeVertex(V,P.Value(),tol);
607 //=======================================================================
608 //function : InsertVertex
609 //purpose : private, insert a vertex from an internal intersection point
611 //=======================================================================
614 HLRTopoBRep_DSFiller::InsertVertex (const Contap_Point& P,
615 const Standard_Real tol,
616 const TopoDS_Edge& E,
617 HLRTopoBRep_Data& DS)
623 V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
626 Standard_Real Par = P.ParameterOnLine();
628 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
629 TopoDS_Vertex curV = DS.Vertex();
630 Standard_Real curP = DS.Parameter();
631 if (P.Value().IsEqual(BRep_Tool::Pnt(curV),
632 BRep_Tool::Tolerance(curV))) {
636 else if (Par < curP) {
637 B.MakeVertex(V,P.Value(),tol);
638 DS.InsertBefore(V,Par);
642 if (!DS.MoreVertex()) {
643 B.MakeVertex(V,P.Value(),tol);
650 //=======================================================================
651 //function : ProcessEdges
652 //purpose : private, split edges with outline vertices
653 //=======================================================================
655 void HLRTopoBRep_DSFiller::ProcessEdges (HLRTopoBRep_Data& DS)
659 TopoDS_Vertex VF,VL,VI;
660 Standard_Real PF,PL,PI;
662 for (DS.InitEdge(); DS.MoreEdge(); DS.NextEdge()) {
663 TopoDS_Edge E = DS.Edge();
664 TopTools_ListOfShape& SplE = DS.AddSplE(E);
665 VF = TopExp::FirstVertex(E);
666 VL = TopExp::LastVertex(E);
667 BRep_Tool::Range(E,PF,PL);
668 VF.Orientation(TopAbs_FORWARD);
669 VL.Orientation(TopAbs_REVERSED);
671 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
674 VI.Orientation(TopAbs_REVERSED);
677 newE.Orientation(TopAbs_FORWARD);
679 B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
681 B.UpdateVertex(VI,PI,newE,BRep_Tool::Tolerance(VI));
682 newE.Orientation(E.Orientation());
686 VF.Orientation(TopAbs_FORWARD);
690 newE.Orientation(TopAbs_FORWARD);
692 B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
694 B.UpdateVertex(VL,PL,newE,BRep_Tool::Tolerance(VL));
695 newE.Orientation(E.Orientation());