1 // Created on: 1996-06-03
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1996-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 #define OPTIMISATION 1
19 #include <Adaptor3d_HCurve.hxx>
20 #include <Adaptor3d_HSurfaceTool.hxx>
21 #include <Bnd_BoundSortBox.hxx>
22 #include <Bnd_Box.hxx>
23 #include <BRepAdaptor_HSurface.hxx>
24 #include <BRepClass_FaceClassifier.hxx>
25 #include <BRepTopAdaptor_TopolTool.hxx>
26 #include <Geom_Line.hxx>
27 #include <GeomAdaptor_Curve.hxx>
28 #include <GeomAdaptor_HCurve.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <IntCurvesFace_Intersector.hxx>
33 #include <IntCurveSurface_HInter.hxx>
34 #include <IntCurveSurface_IntersectionPoint.hxx>
35 #include <IntCurveSurface_SequenceOfPnt.hxx>
36 #include <IntCurveSurface_TheHCurveTool.hxx>
37 #include <IntCurveSurface_ThePolygonOfHInter.hxx>
38 #include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
39 #include <IntCurveSurface_ThePolyhedronToolOfHInter.hxx>
40 #include <Intf_Tool.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <BRep_Tool.hxx>
45 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
46 //=======================================================================
47 //function : SurfaceType
49 //=======================================================================
50 GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
52 return(Adaptor3d_HSurfaceTool::GetType(Hsurface));
54 //=======================================================================
55 //function : IntCurvesFace_Intersector
57 //=======================================================================
58 IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
59 const Standard_Real aTol,
60 const Standard_Boolean aRestr)
66 PtrOnPolyhedron(NULL),
67 PtrOnBndBounding(NULL)
69 BRepAdaptor_Surface surface;
71 surface.Initialize(Face, aRestr);
72 Hsurface = new BRepAdaptor_HSurface(surface);
73 myTopolTool = new BRepTopAdaptor_TopolTool(Hsurface);
75 GeomAbs_SurfaceType SurfaceType = Adaptor3d_HSurfaceTool::GetType(Hsurface);
76 if( (SurfaceType != GeomAbs_Plane)
77 && (SurfaceType != GeomAbs_Cylinder)
78 && (SurfaceType != GeomAbs_Cone)
79 && (SurfaceType != GeomAbs_Sphere)
80 && (SurfaceType != GeomAbs_Torus)) {
81 Standard_Integer nbsu,nbsv;
82 Standard_Real U0,V0,U1,V1;
83 U0 = Hsurface->FirstUParameter();
84 U1 = Hsurface->LastUParameter();
85 V0 = Hsurface->FirstVParameter();
86 V1 = Hsurface->LastVParameter();
88 Standard_Real aURes = Hsurface->UResolution(1.0);
89 Standard_Real aVRes = Hsurface->VResolution(1.0);
91 // Checking correlation between number of samples and length of the face along each axis
92 const Standard_Real aTresh = 100.0;
93 const Standard_Integer aMinSamples = 10;
94 const Standard_Integer aMaxSamples = 40;
95 const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
96 Standard_Real dU = (U1 - U0) / aURes;
97 Standard_Real dV = (V1 - V0) / aVRes;
98 nbsu = myTopolTool->NbSamplesU();
99 nbsv = myTopolTool->NbSamplesV();
100 if (nbsu > aMaxSamples) nbsu = aMaxSamples;
101 if (nbsv > aMaxSamples) nbsv = aMaxSamples;
103 if (Max(dU, dV) > Min(dU, dV) * aTresh)
105 nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
106 if (nbsu < aMinSamples) nbsu = aMinSamples;
107 nbsv = aMaxSamples2 / nbsu;
108 if (nbsv < aMinSamples)
111 nbsu = aMaxSamples2 / aMinSamples;
114 PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
115 new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
118 //=======================================================================
119 //function : InternalCall
121 //=======================================================================
122 void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
123 const Standard_Real parinf,
124 const Standard_Real parsup)
126 if(HICS.IsDone() && HICS.NbPoints() > 0) {
127 //Calculate tolerance for 2d classifier
128 Standard_Real mintol3d = BRep_Tool::Tolerance(face);
129 Standard_Real maxtol3d = mintol3d;
130 Standard_Real mintol2d = Tol, maxtol2d = Tol;
131 TopExp_Explorer anExp(face, TopAbs_EDGE);
132 for(; anExp.More(); anExp.Next())
134 Standard_Real curtol = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Current()));
135 mintol3d = Min(mintol3d, curtol);
136 maxtol3d = Max(maxtol3d, curtol);
138 Standard_Real minres = Max(Hsurface->UResolution(mintol3d), Hsurface->VResolution(mintol3d));
139 Standard_Real maxres = Max(Hsurface->UResolution(maxtol3d), Hsurface->VResolution(maxtol3d));
140 mintol2d = Max(minres, Tol);
141 maxtol2d = Max(maxres, Tol);
143 Handle(BRepTopAdaptor_TopolTool) anAdditionalTool;
144 for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {
145 const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
146 gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
148 //TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
149 TopAbs_State currentstate = myTopolTool->Classify(Puv, mintol2d);
150 if(currentstate == TopAbs_OUT && maxtol2d > mintol2d) {
151 if(anAdditionalTool.IsNull())
153 anAdditionalTool = new BRepTopAdaptor_TopolTool(Hsurface);
155 currentstate = anAdditionalTool->Classify(Puv,maxtol2d);
156 if(currentstate == TopAbs_ON)
158 currentstate = TopAbs_OUT;
159 //Find out nearest edge and it's tolerance
160 anExp.Init(face, TopAbs_EDGE);
161 for(; anExp.More(); anExp.Next())
163 TopoDS_Edge anE = TopoDS::Edge(anExp.Current());
164 Standard_Real curtol = BRep_Tool::Tolerance(anE);
165 Standard_Real tol2d = Max(Hsurface->UResolution(curtol), Hsurface->VResolution(curtol));
166 tol2d = Max(tol2d, Tol);
168 Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(anE, face, f, l);
169 Geom2dAPI_ProjectPointOnCurve aProj(Puv, aPC, f, l);
170 if(aProj.NbPoints() > 0)
172 Standard_Real d = aProj.LowerDistance();
175 //Nearest edge is found, state is really ON
176 currentstate = TopAbs_ON;
183 if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) {
184 Standard_Real HICSW = HICSPointindex.W();
185 if(HICSW >= parinf && HICSW <= parsup ) {
186 Standard_Real U = HICSPointindex.U();
187 Standard_Real V = HICSPointindex.V();
188 Standard_Real W = HICSW;
189 IntCurveSurface_TransitionOnCurve transition = HICSPointindex.Transition();
190 gp_Pnt pnt = HICSPointindex.Pnt();
191 // state = currentstate;
192 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
193 Standard_Integer anIntState = (currentstate == TopAbs_IN) ? 0 : 1;
194 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
196 if(transition != IntCurveSurface_Tangent && face.Orientation()==TopAbs_REVERSED) {
197 if(transition == IntCurveSurface_In)
198 transition = IntCurveSurface_Out;
200 transition = IntCurveSurface_In;
202 //----- Insertion du point
204 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
206 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
207 mySeqState.Append(anIntState);
208 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
211 Standard_Integer i = 1;
212 Standard_Integer b = nbpnt+1;
214 const IntCurveSurface_IntersectionPoint& Pnti=SeqPnt.Value(i);
215 Standard_Real wi = Pnti.W();
216 if(wi >= W) { b=i; i=nbpnt; }
219 IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
220 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
221 // if(b>nbpnt) { SeqPnt.Append(PPP); }
222 // else if(b>0) { SeqPnt.InsertBefore(b,PPP); }
225 mySeqState.Append(anIntState);
227 SeqPnt.InsertBefore(b,PPP);
228 mySeqState.InsertBefore(b, anIntState);
230 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
236 } //-- classifier state is IN or ON
237 } //-- Loop on Intersection points.
240 //=======================================================================
243 //=======================================================================
244 void IntCurvesFace_Intersector::Perform(const gp_Lin& L,
245 const Standard_Real ParMin,
246 const Standard_Real ParMax)
248 done = Standard_True;
253 IntCurveSurface_HInter HICS;
254 Handle(Geom_Line) geomline = new Geom_Line(L);
255 GeomAdaptor_Curve LL(geomline);
256 Handle(GeomAdaptor_HCurve) HLL = new GeomAdaptor_HCurve(LL);
257 Standard_Real parinf=ParMin;
258 Standard_Real parsup=ParMax;
260 if(PtrOnPolyhedron == NULL) {
261 HICS.Perform(HLL,Hsurface);
268 ((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding(),
270 if(bndTool.NbSegments() == 0)
272 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
273 Standard_Real pinf = bndTool.BeginParam(nbseg);
274 Standard_Real psup = bndTool.EndParam(nbseg);
275 Standard_Real pppp = 0.05*(psup-pinf);
278 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
279 if(nbseg==1) { parinf=pinf; parsup=psup; }
281 if(parinf>pinf) parinf = pinf;
282 if(parsup<psup) parsup = psup;
285 if(parinf>ParMax) { return; }
286 if(parsup<ParMin) { return; }
287 if(parinf<ParMin) parinf=ParMin;
288 if(parsup>ParMax) parsup=ParMax;
289 if(parinf>(parsup-1e-9)) return;
290 IntCurveSurface_ThePolygonOfHInter polygon(HLL,
295 if(PtrOnBndBounding==NULL) {
296 PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
297 IntCurveSurface_ThePolyhedronOfHInter *thePolyh=
298 (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
299 ((Bnd_BoundSortBox *)(PtrOnBndBounding))->
300 Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
301 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
306 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
307 *((Bnd_BoundSortBox *)PtrOnBndBounding));
312 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
316 InternalCall(HICS,parinf,parsup);
318 //=======================================================================
321 //=======================================================================
322 void IntCurvesFace_Intersector::Perform(const Handle(Adaptor3d_HCurve)& HCu,
323 const Standard_Real ParMin,
324 const Standard_Real ParMax)
326 done = Standard_True;
328 // Modified by skv - Wed Sep 3 16:14:10 2003 OCC578 Begin
330 // Modified by skv - Wed Sep 3 16:14:11 2003 OCC578 End
332 IntCurveSurface_HInter HICS;
335 Standard_Real parinf=ParMin;
336 Standard_Real parsup=ParMax;
338 if(PtrOnPolyhedron == NULL) {
339 HICS.Perform(HCu,Hsurface);
342 parinf = IntCurveSurface_TheHCurveTool::FirstParameter(HCu);
343 parsup = IntCurveSurface_TheHCurveTool::LastParameter(HCu);
344 if(parinf<ParMin) parinf = ParMin;
345 if(parsup>ParMax) parsup = ParMax;
346 if(parinf>(parsup-1e-9)) return;
347 Standard_Integer nbs;
348 nbs = IntCurveSurface_TheHCurveTool::NbSamples(HCu,parinf,parsup);
350 IntCurveSurface_ThePolygonOfHInter polygon(HCu,
355 if(PtrOnBndBounding==NULL) {
356 PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
357 IntCurveSurface_ThePolyhedronOfHInter *thePolyh=(IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
358 ((Bnd_BoundSortBox *)(PtrOnBndBounding))->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
359 IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
364 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
365 *((Bnd_BoundSortBox *)PtrOnBndBounding));
370 *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
373 InternalCall(HICS,parinf,parsup);
376 //============================================================================
377 Bnd_Box IntCurvesFace_Intersector::Bounding() const {
378 if(PtrOnPolyhedron !=NULL) {
379 return(((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding());
386 TopAbs_State IntCurvesFace_Intersector::ClassifyUVPoint(const gp_Pnt2d& Puv) const {
387 TopAbs_State state = myTopolTool->Classify(Puv,1e-7);
390 //============================================================================
391 void IntCurvesFace_Intersector::Destroy() {
392 if(PtrOnPolyhedron !=NULL) {
393 delete (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
394 PtrOnPolyhedron = NULL;
396 if(PtrOnBndBounding !=NULL) {
397 delete (Bnd_BoundSortBox *)PtrOnBndBounding;
398 PtrOnBndBounding=NULL;