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.
18 #include <AppDef_BSplineCompute.hxx>
19 #include <AppDef_MultiLine.hxx>
20 #include <AppParCurves_MultiBSpCurve.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRep_TEdge.hxx>
23 #include <BRep_Tool.hxx>
24 #include <BRepApprox_Approx.hxx>
25 #include <BRepApprox_ApproxLine.hxx>
26 #include <BRepExtrema_ExtPC.hxx>
27 #include <BRepTopAdaptor_HVertex.hxx>
28 #include <BRepTopAdaptor_TopolTool.hxx>
29 #include <Contap_Contour.hxx>
30 #include <Contap_Line.hxx>
31 #include <Contap_Point.hxx>
32 #include <Extrema_LocateExtPC.hxx>
33 #include <Geom2d_BSplineCurve.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <Geom_Circle.hxx>
37 #include <Geom_Line.hxx>
38 #include <Geom_Surface.hxx>
39 #include <GeomProjLib.hxx>
40 #include <HLRTopoBRep_Data.hxx>
41 #include <HLRTopoBRep_DSFiller.hxx>
42 #include <HLRTopoBRep_FaceIsoLiner.hxx>
43 #include <math_Vector.hxx>
44 #include <Precision.hxx>
45 #include <Standard_ProgramError.hxx>
46 #include <TColgp_Array1OfPnt.hxx>
47 #include <TColgp_Array1OfPnt2d.hxx>
48 #include <TColStd_Array1OfInteger.hxx>
49 #include <TColStd_Array1OfReal.hxx>
51 #include <TopExp_Explorer.hxx>
53 #include <TopoDS_Edge.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <TopoDS_Shape.hxx>
56 #include <TopoDS_Vertex.hxx>
58 //=======================================================================
60 //purpose : explore the faces and insert them
61 //=======================================================================
63 void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
66 BRepTopAdaptor_MapOfShapeTool& MST,
67 const Standard_Integer nbIso)
69 TopTools_MapOfShape ShapeMap;
70 TopExp_Explorer ex(S,TopAbs_FACE);
72 Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0;
73 Standard_Integer f = 0;
76 if (ShapeMap.Add(ex.Current())) {
78 TopoDS_Face S1 = TopoDS::Face(ex.Current());
79 S1.Orientation(TopAbs_FORWARD);
80 Handle(BRepTopAdaptor_TopolTool) Domain;
81 Handle(Adaptor3d_Surface) Surface;
83 BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1);
84 Domain = BRT.GetTopolTool();
85 Surface = BRT.GetSurface();
88 BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion());
90 Domain = BRT.GetTopolTool();
91 Surface = BRT.GetSurface();
93 FO.Perform(Surface, Domain);
96 InsertFace(f,S1,FO,DS,withPCurve);
98 if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
105 //=======================================================================
106 //function : InsertFace
107 //purpose : private, insert the outlines of a face
108 //=======================================================================
110 void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
111 const TopoDS_Face& F,
113 HLRTopoBRep_Data& DS,
114 const Standard_Boolean withPCurve)
116 // Insert the intersections of FO in DS
118 const Standard_Real tol = BRep_Tool::Tolerance(F);
119 TopTools_ListOfShape& IntL = DS.AddIntL(F);
120 TopTools_ListOfShape& OutL = DS.AddOutL(F);
124 TopTools_MapOfShape VM;
125 TopExp_Explorer ex(F,TopAbs_EDGE);
127 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
128 if (BRep_Tool::IsClosed(E,F)) {
129 TopExp::Vertices(E,VF,VL);
137 const Standard_Integer NbLines = FO.NbLines();
138 Standard_Integer CurLine;
139 for (CurLine = 1; CurLine <= NbLines; CurLine++)
141 const Contap_Line& Line = FO.Line(CurLine);
142 const Standard_Integer NbPoints = Line.NbVertex();
143 Standard_Integer CurPoint;
144 if (Line.TypeContour() == Contap_Restriction)
146 // OutLine on restriction
147 TopoDS_Edge E = (*(BRepAdaptor_Curve2d*)(Line.Arc().get())).Edge();
149 TopExp::Vertices(E,VF,VL);
150 // insert the Internal points.
152 for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
153 Contap_Point P = Line.Vertex(CurPoint);
154 if (P.IsInternal()) {
155 if (P.Value().IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) {
156 if (P.Value().IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) {
157 InsertVertex(P,tol,E,DS);
165 for (CurPoint = 1; CurPoint <= NbPoints; CurPoint++) {
167 const Contap_Point PF = Line.Vertex(CurPoint);
168 if (PF.IsInternal() && CurPoint != 1)
171 VF = MakeVertex(PF,tol,DS);
172 const Standard_Real parF = PF.ParameterOnLine();
174 if (CurPoint < NbPoints) {
175 const Contap_Point PL = Line.Vertex(CurPoint+1);
176 VL = MakeVertex(PL,tol,DS);
177 const Standard_Real parL = PL.ParameterOnLine();
179 if( (parL-parF) > Precision::PConfusion() ) {
181 Handle(Geom_Curve) C;
182 Handle(Geom2d_Curve) C2d;
183 Standard_Real first = parF;
184 Standard_Real last = parL;
185 Standard_Boolean InsuffisantNumberOfPoints=Standard_False;
187 switch (Line.TypeContour()) {
191 C = new Geom_Line(Line.Line());
193 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
194 Standard_Real Tol = 1e-7;
195 C2d = GeomProjLib::Curve2d(C,first,last,S,Tol);
202 C = new Geom_Circle(Line.Circle());
205 Handle(Geom_Surface) S = BRep_Tool::Surface(F,Loc);
206 if (!Loc.IsIdentity()) {
207 S = Handle(Geom_Surface)::DownCast(S->Transformed(Loc.Transformation()));
209 Standard_Real Tol = 1e-7;
210 C2d = GeomProjLib::Curve2d(C,first,last,S,Tol);
215 case Contap_Walking :
218 Standard_Integer ipF = Standard_Integer(parF);
219 Standard_Integer ipL = Standard_Integer(parL);
222 InsuffisantNumberOfPoints=Standard_True;
223 //std::cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<std::endl;
226 else if(ipL-ipF < 6) {
227 // compute the tangents
228 Contap_SurfFunction& SFunc =
229 FO.SurfaceFunction();
231 Standard_Boolean isTg1,isTg2;
234 math_Vector UV(1,2),F(1,1);
236 Line.Point(ipF).ParametersOnS2(UV(1),UV(2));
238 isTg1 = SFunc.IsTangent();
240 tg1 = SFunc.Direction3d();
241 if (withPCurve) uv1 = SFunc.Direction2d();
244 Line.Point(ipL).ParametersOnS2(UV(1),UV(2));
246 isTg2 = SFunc.IsTangent();
248 tg2 = SFunc.Direction3d();
249 if (withPCurve) uv2 = SFunc.Direction2d();
252 Standard_Integer nbp = ipL - ipF + 1;
253 AppDef_MultiLine MLine(nbp);
254 Standard_Integer nb2d = 0;
255 if (withPCurve) nb2d = 1;
257 for (Standard_Integer i = 1; i <= nbp; i++) {
258 AppDef_MultiPointConstraint MP(1, nb2d);
259 MP.SetPoint(1,Line.Point(i + ipF - 1).Value());
261 Line.Point(i + ipF - 1).ParametersOnS2(UV(1),UV(2));
262 MP.SetPoint2d(2,gp_Pnt2d(UV(1),UV(2)));
265 if (i == 1 && !isTg1) {
267 if (withPCurve) MP.SetTang2d(2,uv1);
269 if (i == nbp && !isTg2) {
271 if (withPCurve) MP.SetTang2d(2,uv2);
273 MLine.SetValue(i,MP);
275 AppDef_BSplineCompute interp;
276 interp.Interpol(MLine);
277 AppParCurves_MultiBSpCurve TheCurve = interp.Value();
278 Standard_Integer Degree = TheCurve.Degree();
279 TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
280 TheCurve.Curve(1,Poles);
281 C = new Geom_BSplineCurve(Poles,
283 TheCurve.Multiplicities(),
286 TColgp_Array1OfPnt2d Pol2d(1,TheCurve.NbPoles());
287 TheCurve.Curve(2,Pol2d);
288 C2d = new Geom2d_BSplineCurve(Pol2d,
290 TheCurve.Multiplicities(),
297 else if(ipL-ipF < 5) {
298 const Standard_Integer nbp = ipL - ipF + 1;
299 TColStd_Array1OfReal knots(1,nbp);
300 TColStd_Array1OfInteger mults(1,nbp);
301 TColgp_Array1OfPnt Points(1,nbp);
303 for(Standard_Integer i=1;i<=nbp;i++) {
304 knots.SetValue(i,(Standard_Real)i);
306 Points.SetValue(i,Line.Point(i+ipF-1).Value());
308 mults(1)=mults(nbp)=2;
309 C = new Geom_BSplineCurve(Points,knots,mults,1);
312 TColgp_Array1OfPnt2d Points2d(1,nbp);
313 for(Standard_Integer i=1;i<=nbp;i++) {
315 Line.Point(i+ipF-1).ParametersOnS2(u,v);
316 Points2d.SetValue(i,gp_Pnt2d(u,v));
318 C2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
324 const Standard_Integer nbp = ipL - ipF + 1;
325 TColStd_Array1OfReal knots(1,nbp);
326 TColStd_Array1OfInteger mults(1,nbp);
327 TColgp_Array1OfPnt Points(1,nbp);
329 Standard_Real Maxx,Maxy,Maxz,Maxu,Maxv;
330 Standard_Real Minx,Miny,Minz,Minu,Minv;
331 Maxx=Maxy=Maxz=Maxu=Maxv=-RealLast();
332 Minx=Miny=Minz=Minu=Minv=RealLast();
334 for(Standard_Integer i=1;i<=nbp;i++) {
335 knots.SetValue(i,(Standard_Real)i);
337 const gp_Pnt& P= Line.Point(i+ipF-1).Value();
338 if(P.X()<Minx) Minx=P.X();
339 if(P.Y()<Miny) Miny=P.Y();
340 if(P.Z()<Minz) Minz=P.Z();
341 if(P.X()>Maxx) Maxx=P.X();
342 if(P.Y()>Maxy) Maxy=P.Y();
343 if(P.Z()>Maxz) Maxz=P.Z();
344 Points.SetValue(i,P);
346 mults(1)=mults(nbp)=2;
347 Handle(Geom_BSplineCurve) AppC;
348 Handle(Geom2d_BSplineCurve) AppC2d;
349 AppC = new Geom_BSplineCurve(Points,knots,mults,1);
352 TColgp_Array1OfPnt2d Points2d(1,nbp);
353 for(Standard_Integer i=1;i<=nbp;i++) {
355 Line.Point(i+ipF-1).ParametersOnS2(u,v);
360 Points2d.SetValue(i,gp_Pnt2d(u,v));
362 AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
367 Handle(BRepApprox_ApproxLine) AppLine;
368 Handle(Geom2d_BSplineCurve) CNull;
369 AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
371 Standard_Integer dmin=4,dmax=8,niter=0;
372 Standard_Boolean tg= Standard_False;
373 BRepApprox_Approx Approx;
374 Standard_Real TOL3d,TOL2d,TOL=0.0001;
376 Maxx-=Minx; Maxy-=Miny; Maxz-=Minz;
377 Maxu-=Minu; Maxv-=Minv;
378 if(Maxy>Maxx) Maxx=Maxy;
379 if(Maxz>Maxx) Maxx=Maxy;
380 if(Maxv>Maxu) Maxu=Maxv;
382 TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
383 TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
385 //-- std::cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<std::endl;
387 Approx.SetParameters(TOL3d, TOL2d, dmin, dmax, niter, 30, tg);
388 Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
389 if (!Approx.IsDone()) {
396 const AppParCurves_MultiBSpCurve& AppVal = Approx.Value(1);
397 TColgp_Array1OfPnt poles3d(1,AppVal.NbPoles());
398 AppVal.Curve(1,poles3d);
399 C = new Geom_BSplineCurve(poles3d,AppVal.Knots(),AppVal.Multiplicities(),AppVal.Degree());
401 const AppParCurves_MultiBSpCurve& AppVal2 = Approx.Value(2);
402 TColgp_Array1OfPnt2d poles2d(1,AppVal2.NbPoles());
403 AppVal2.Curve(2,poles2d);
404 C2d = new Geom2d_BSplineCurve(poles2d,AppVal2.Knots(),AppVal2.Multiplicities(),AppVal2.Degree());
405 first = C2d->FirstParameter();
406 last = C2d->LastParameter();
412 case Contap_Restriction :
414 throw Standard_ProgramError("HLRTopoBRep_DSFiller::InsertFace : Restriction");
419 // compute the PCurve
421 if (!InsuffisantNumberOfPoints) {
425 VF.Orientation(TopAbs_FORWARD);
426 VL.Orientation(TopAbs_REVERSED);
429 B.Range(E,first,last);
432 B.UpdateEdge(E,C2d,F,BRep_Tool::Tolerance(F));
435 // add the edge in the DS
445 //Correction of internal outlines: unite coinciding vertices
446 const Standard_Real SqTol = tol*tol;
447 TopTools_ListIteratorOfListOfShape itl1(IntL);
448 for (; itl1.More(); itl1.Next())
450 TopoDS_Edge anIntLine = TopoDS::Edge(itl1.Value());
451 anIntLine.Orientation(TopAbs_FORWARD);
452 TopoDS_Vertex aVer [2];
453 TopExp::Vertices(anIntLine, aVer[0], aVer[1]);
454 TopTools_ListIteratorOfListOfShape itl2 = itl1;
455 for (; itl2.More(); itl2.Next())
457 TopoDS_Edge anIntLine2 = TopoDS::Edge(itl2.Value());
458 anIntLine2.Orientation(TopAbs_FORWARD);
459 if (anIntLine2.IsSame(anIntLine))
461 TopoDS_Vertex aVer2 [2];
462 TopExp::Vertices(anIntLine2, aVer2[0], aVer2[1]);
463 for (Standard_Integer i = 0; i < 2; i++)
465 if (i == 1 && aVer[0].IsSame(aVer[1]))
467 gp_Pnt Pnt1 = BRep_Tool::Pnt(aVer[i]);
468 for (Standard_Integer j = 0; j < 2; j++)
470 if (aVer[i].IsSame(aVer2[j]))
472 gp_Pnt Pnt2 = BRep_Tool::Pnt(aVer2[j]);
473 if (Pnt1.SquareDistance(Pnt2) <= SqTol)
476 aBB.Remove(anIntLine2, aVer2[j]);
477 aVer[i].Orientation((j==0)? TopAbs_FORWARD : TopAbs_REVERSED);
478 aBB.Add(anIntLine2, aVer[i]);
486 //=======================================================================
487 //function : MakeVertex
488 //purpose : private, make a vertex from an intersection point
489 //=======================================================================
492 HLRTopoBRep_DSFiller::MakeVertex (const Contap_Point& P,
493 const Standard_Real tol,
494 HLRTopoBRep_Data& DS)
499 V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
503 // if on arc, insert in the DS
505 const TopoDS_Edge& E = (*(BRepAdaptor_Curve2d*)(P.Arc().get())).Edge();
506 Standard_Real Par = P.ParameterOnArc();
507 const gp_Pnt& P3d = P.Value();
509 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
510 TopoDS_Vertex curV = DS.Vertex();
511 Standard_Real curP = DS.Parameter();
512 const gp_Pnt& PPP=BRep_Tool::Pnt(curV);
513 Standard_Real TTT=BRep_Tool::Tolerance(curV);
514 if (P3d.IsEqual(PPP,TTT)) {
518 else if (Par < curP) {
519 B.MakeVertex(V,P.Value(),tol);
520 DS.InsertBefore(V,Par);
524 if (!DS.MoreVertex()) {
525 B.MakeVertex(V,P.Value(),tol);
530 // if internal create a vertex and insert in the DS
532 B.MakeVertex(V,P.Value(),tol);
542 //=======================================================================
543 //function : InsertVertex
544 //purpose : private, insert a vertex from an internal intersection point
546 //=======================================================================
549 HLRTopoBRep_DSFiller::InsertVertex (const Contap_Point& P,
550 const Standard_Real tol,
551 const TopoDS_Edge& E,
552 HLRTopoBRep_Data& DS)
558 V = Handle(BRepTopAdaptor_HVertex)::DownCast(P.Vertex())->Vertex();
561 Standard_Real Par = P.ParameterOnLine();
563 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
564 TopoDS_Vertex curV = DS.Vertex();
565 Standard_Real curP = DS.Parameter();
566 if (P.Value().IsEqual(BRep_Tool::Pnt(curV),
567 BRep_Tool::Tolerance(curV))) {
571 else if (Par < curP) {
572 B.MakeVertex(V,P.Value(),tol);
573 DS.InsertBefore(V,Par);
577 if (!DS.MoreVertex()) {
578 B.MakeVertex(V,P.Value(),tol);
585 //=======================================================================
586 //function : ProcessEdges
587 //purpose : private, split edges with outline vertices
588 //=======================================================================
590 void HLRTopoBRep_DSFiller::ProcessEdges (HLRTopoBRep_Data& DS)
594 TopoDS_Vertex VF,VL,VI;
595 Standard_Real PF,PL,PI;
597 for (DS.InitEdge(); DS.MoreEdge(); DS.NextEdge()) {
598 TopoDS_Edge E = DS.Edge();
599 TopTools_ListOfShape& SplE = DS.AddSplE(E);
600 VF = TopExp::FirstVertex(E);
601 VL = TopExp::LastVertex(E);
602 BRep_Tool::Range(E,PF,PL);
603 VF.Orientation(TopAbs_FORWARD);
604 VL.Orientation(TopAbs_REVERSED);
606 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
609 VI.Orientation(TopAbs_REVERSED);
612 newE.Orientation(TopAbs_FORWARD);
614 B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
616 B.UpdateVertex(VI,PI,newE,BRep_Tool::Tolerance(VI));
617 newE.Orientation(E.Orientation());
621 VF.Orientation(TopAbs_FORWARD);
625 newE.Orientation(TopAbs_FORWARD);
627 B.UpdateVertex(VF,PF,newE,BRep_Tool::Tolerance(VF));
629 B.UpdateVertex(VL,PL,newE,BRep_Tool::Tolerance(VL));
630 newE.Orientation(E.Orientation());