Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1997-10-13 |
2 | // Created by: Roman BORISOV | |
3 | // Copyright (c) 1997-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
42cf5bc1 | 17 | |
18 | #include <Adaptor3d_Curve.hxx> | |
19 | #include <Approx_CurveOnSurface.hxx> | |
20 | #include <BRep_Builder.hxx> | |
7fd59977 | 21 | #include <BRepAdaptor_Curve.hxx> |
42cf5bc1 | 22 | #include <BRepAdaptor_Surface.hxx> |
42cf5bc1 | 23 | #include <BRepAlgo_NormalProjection.hxx> |
977ad983 | 24 | #include <BRepAlgoAPI_Section.hxx> |
42cf5bc1 | 25 | #include <BRepLib_MakeEdge.hxx> |
7fd59977 | 26 | #include <BRepLib_MakeVertex.hxx> |
27 | #include <BRepLib_MakeWire.hxx> | |
42cf5bc1 | 28 | #include <BRepTopAdaptor_FClass2d.hxx> |
29 | #include <Geom2d_BSplineCurve.hxx> | |
7fd59977 | 30 | #include <Geom2d_Curve.hxx> |
42cf5bc1 | 31 | #include <Geom2d_TrimmedCurve.hxx> |
c22b52d6 | 32 | #include <Geom2dAdaptor_Curve.hxx> |
7fd59977 | 33 | #include <Geom_BSplineCurve.hxx> |
34 | #include <GeomAdaptor.hxx> | |
7fd59977 | 35 | #include <Precision.hxx> |
42cf5bc1 | 36 | #include <ProjLib_HCompProjectedCurve.hxx> |
42cf5bc1 | 37 | #include <StdFail_NotDone.hxx> |
7fd59977 | 38 | #include <TColgp_Array1OfPnt2d.hxx> |
7fd59977 | 39 | #include <TColStd_Array1OfInteger.hxx> |
42cf5bc1 | 40 | #include <TColStd_Array1OfReal.hxx> |
42cf5bc1 | 41 | #include <TopExp.hxx> |
42 | #include <TopExp_Explorer.hxx> | |
43 | #include <TopoDS.hxx> | |
44 | #include <TopoDS_Edge.hxx> | |
45 | #include <TopoDS_Shape.hxx> | |
42cf5bc1 | 46 | #include <TopTools_HSequenceOfShape.hxx> |
7fd59977 | 47 | |
0797d9d3 | 48 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 49 | #include <OSD_Timer.hxx> |
50 | ||
51 | OSD_Chronometer chr_total, chr_init, chr_approx, chr_booltool; | |
52 | ||
53 | Standard_Real t_total, t_init, t_approx, t_booltool; | |
54 | Standard_IMPORT Standard_Real t_init_point, t_dicho_bound; | |
55 | Standard_IMPORT Standard_Integer init_point_count, dicho_bound_count; | |
56 | ||
57 | void InitChron(OSD_Chronometer& ch) | |
58 | { | |
59 | ch.Reset(); | |
60 | ch.Start(); | |
61 | } | |
62 | ||
63 | void ResultChron( OSD_Chronometer & ch, Standard_Real & time) | |
64 | { | |
65 | Standard_Real tch ; | |
66 | ch.Stop(); | |
67 | ch.Show(tch); | |
68 | time=time +tch; | |
69 | } | |
70 | ||
71 | #endif | |
72 | //======================================================================= | |
73 | //function : BRepAlgo_NormalProjection | |
74 | //purpose : | |
75 | //======================================================================= | |
76 | ||
77 | BRepAlgo_NormalProjection::BRepAlgo_NormalProjection() | |
e05c25c1 | 78 | : myIsDone(Standard_False), myMaxDist(-1.), |
79 | myWith3d(Standard_True), myFaceBounds(Standard_True) | |
7fd59977 | 80 | { |
81 | BRep_Builder BB; | |
82 | BB.MakeCompound(TopoDS::Compound(myToProj)); | |
7fd59977 | 83 | SetDefaultParams(); |
7fd59977 | 84 | } |
85 | ||
86 | //======================================================================= | |
87 | //function : BRepAlgo_NormalProjection | |
88 | //purpose : | |
89 | //======================================================================= | |
90 | ||
91 | BRepAlgo_NormalProjection::BRepAlgo_NormalProjection(const TopoDS_Shape& S) | |
e05c25c1 | 92 | : myIsDone(Standard_False), myMaxDist(-1.), |
93 | myWith3d(Standard_True), myFaceBounds(Standard_True) | |
7fd59977 | 94 | { |
95 | BRep_Builder BB; | |
96 | BB.MakeCompound(TopoDS::Compound(myToProj)); | |
97 | SetDefaultParams(); | |
7fd59977 | 98 | Init(S); |
99 | } | |
100 | ||
101 | //======================================================================= | |
102 | //function : Init | |
103 | //purpose : | |
104 | //======================================================================= | |
105 | ||
106 | void BRepAlgo_NormalProjection::Init(const TopoDS_Shape& S) | |
107 | { | |
108 | myShape = S; | |
109 | } | |
110 | ||
111 | //======================================================================= | |
112 | //function : Add | |
113 | //purpose : | |
114 | //======================================================================= | |
115 | ||
116 | void BRepAlgo_NormalProjection::Add(const TopoDS_Shape& ToProj) | |
117 | { | |
118 | BRep_Builder BB; | |
119 | BB.Add(myToProj, ToProj); | |
120 | } | |
121 | ||
122 | //======================================================================= | |
123 | //function : SetParams | |
124 | //purpose : | |
125 | //======================================================================= | |
126 | ||
127 | void BRepAlgo_NormalProjection::SetParams(const Standard_Real Tol3D, | |
128 | const Standard_Real Tol2D, | |
129 | const GeomAbs_Shape InternalContinuity, | |
130 | const Standard_Integer MaxDegree, | |
131 | const Standard_Integer MaxSeg) | |
132 | { | |
133 | myTol3d = Tol3D; | |
134 | myTol2d = Tol2D; | |
135 | myContinuity = InternalContinuity; | |
136 | myMaxDegree = MaxDegree; | |
137 | myMaxSeg = MaxSeg; | |
138 | } | |
139 | ||
140 | //======================================================================= | |
141 | //function : SetDefaultParams | |
142 | //purpose : | |
143 | //======================================================================= | |
144 | ||
145 | void BRepAlgo_NormalProjection::SetDefaultParams() | |
146 | { | |
147 | myTol3d = 1.e-4; | |
148 | myTol2d = Pow(myTol3d, 2./3); | |
4ec4e4e8 | 149 | myContinuity = GeomAbs_C1; |
7fd59977 | 150 | myMaxDegree = 14; |
151 | myMaxSeg = 16; | |
152 | } | |
153 | ||
154 | //======================================================================= | |
155 | //function : SetLimits | |
156 | //purpose : | |
157 | //======================================================================= | |
158 | ||
159 | void BRepAlgo_NormalProjection::SetLimit(const Standard_Boolean FaceBounds) | |
160 | { | |
161 | myFaceBounds = FaceBounds; | |
162 | } | |
163 | ||
164 | //======================================================================= | |
165 | //function : SetMaxDistance | |
166 | //purpose : | |
167 | //======================================================================= | |
168 | ||
169 | void BRepAlgo_NormalProjection::SetMaxDistance(const Standard_Real MaxDist) | |
170 | { | |
171 | myMaxDist = MaxDist; | |
172 | } | |
173 | ||
174 | //======================================================================= | |
175 | //function : Compute3d | |
176 | //purpose : | |
177 | //======================================================================= | |
178 | ||
179 | void BRepAlgo_NormalProjection::Compute3d(const Standard_Boolean With3d) | |
180 | { | |
181 | myWith3d = With3d; | |
182 | } | |
183 | ||
184 | //======================================================================= | |
185 | //function : Build | |
186 | //purpose : | |
187 | //======================================================================= | |
188 | ||
189 | void BRepAlgo_NormalProjection::Build() | |
190 | { | |
0797d9d3 | 191 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 192 | Standard_Integer init_count = 0, approx_count = 0, booltool_count = 0; |
193 | t_total = 0; | |
194 | t_init = 0; | |
195 | t_approx = 0; | |
196 | t_booltool = 0; | |
197 | ||
198 | t_init_point = 0; | |
199 | init_point_count = 0; | |
200 | ||
201 | t_dicho_bound = 0; | |
202 | dicho_bound_count = 0; | |
203 | ||
204 | InitChron(chr_total); | |
205 | #endif | |
206 | myIsDone = Standard_False; | |
c22b52d6 | 207 | |
7fd59977 | 208 | Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape(); |
209 | Handle(TopTools_HSequenceOfShape) Faces = new TopTools_HSequenceOfShape(); | |
210 | TopTools_ListOfShape DescenList; | |
211 | Standard_Integer NbEdges = 0, NbFaces = 0, i, j, k; | |
212 | TopExp_Explorer ExpOfWire, ExpOfShape; | |
213 | Standard_Real Udeb, Ufin; | |
214 | TopoDS_Shape VertexRes; | |
215 | Standard_Boolean Only3d, Only2d, Elementary; | |
216 | ||
217 | // for isoparametric cases | |
218 | TColgp_Array1OfPnt2d Poles(1, 2); | |
219 | TColStd_Array1OfReal Knots(1, 2); | |
220 | TColStd_Array1OfInteger Mults(1,2); | |
221 | Standard_Integer Deg; | |
222 | Deg = 1; | |
223 | Mults(1) = Deg + 1; | |
224 | Mults(2) = Deg + 1; | |
225 | // | |
226 | ||
227 | for(ExpOfWire.Init(myToProj, TopAbs_EDGE); | |
228 | ExpOfWire.More(); | |
229 | ExpOfWire.Next(), NbEdges++) { | |
230 | Edges->Append(ExpOfWire.Current()); | |
231 | } | |
232 | ||
233 | for(ExpOfShape.Init(myShape, TopAbs_FACE); | |
234 | ExpOfShape.More(); | |
235 | ExpOfShape.Next(), NbFaces++) { | |
236 | Faces->Append(ExpOfShape.Current()); | |
237 | } | |
238 | ||
239 | BRep_Builder BB; | |
240 | BB.MakeCompound(TopoDS::Compound(myRes)); | |
241 | BB.MakeCompound(TopoDS::Compound(VertexRes)); | |
242 | Standard_Boolean YaVertexRes = Standard_False; | |
243 | ||
244 | for(i = 1; i <= NbEdges; i++){ | |
245 | DescenList.Clear(); | |
c22b52d6 | 246 | Handle(BRepAdaptor_Curve) hcur = new BRepAdaptor_Curve (TopoDS::Edge(Edges->Value(i))); |
247 | Elementary = IsElementary(*hcur); | |
7fd59977 | 248 | for(j = 1; j <= NbFaces; j++){ |
c22b52d6 | 249 | Handle(BRepAdaptor_Surface) hsur = new BRepAdaptor_Surface (TopoDS::Face(Faces->Value(j))); |
7fd59977 | 250 | |
251 | // computation of TolU and TolV | |
252 | ||
253 | Standard_Real TolU, TolV; | |
254 | ||
255 | TolU = hsur->UResolution(myTol3d)/20; | |
256 | TolV = hsur->VResolution(myTol3d)/20; | |
257 | // Projection | |
0797d9d3 | 258 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 259 | InitChron(chr_init); |
260 | #endif | |
c22b52d6 | 261 | Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (hsur, hcur, TolU, TolV, myMaxDist); |
0797d9d3 | 262 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 263 | ResultChron(chr_init,t_init); |
264 | init_count++; | |
265 | #endif | |
266 | // | |
7fd59977 | 267 | TopoDS_Shape prj; |
268 | Standard_Boolean Degenerated = Standard_False; | |
269 | gp_Pnt2d P2d, Pdeb, Pfin; | |
270 | gp_Pnt P; | |
271 | Standard_Real UIso, VIso; | |
272 | ||
c22b52d6 | 273 | Handle(Adaptor2d_Curve2d) HPCur; |
7fd59977 | 274 | Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection |
275 | ||
c22b52d6 | 276 | for(k = 1; k <= HProjector->NbCurves(); k++){ |
277 | if(HProjector->IsSinglePnt(k, P2d)){ | |
0797d9d3 | 278 | #ifdef OCCT_DEBUG |
04232180 | 279 | std::cout << "Projection of edge "<<i<<" on face "<<j; |
280 | std::cout << " is punctual"<<std::endl<<std::endl; | |
7fd59977 | 281 | #endif |
c22b52d6 | 282 | HProjector->GetSurface()->D0(P2d.X(), P2d.Y(), P); |
7fd59977 | 283 | prj = BRepLib_MakeVertex(P).Shape(); |
284 | DescenList.Append(prj); | |
285 | BB.Add(VertexRes, prj); | |
286 | YaVertexRes = Standard_True; | |
287 | ||
288 | myAncestorMap.Bind(prj, Edges->Value(i)); | |
289 | } | |
290 | else { | |
291 | Only2d = Only3d = Standard_False; | |
c22b52d6 | 292 | HProjector->Bounds(k, Udeb, Ufin); |
7fd59977 | 293 | |
294 | /**************************************************************/ | |
c22b52d6 | 295 | if (HProjector->IsUIso(k, UIso)) { |
0797d9d3 | 296 | #ifdef OCCT_DEBUG |
04232180 | 297 | std::cout << "Projection of edge "<<i<<" on face "<<j; |
298 | std::cout << " is U-isoparametric"<<std::endl<<std::endl; | |
7fd59977 | 299 | #endif |
c22b52d6 | 300 | HProjector->D0(Udeb, Pdeb); |
301 | HProjector->D0(Ufin, Pfin); | |
7fd59977 | 302 | Poles(1) = Pdeb; |
303 | Poles(2) = Pfin; | |
304 | Knots(1) = Udeb; | |
305 | Knots(2) = Ufin; | |
306 | Handle(Geom2d_BSplineCurve) BS2d = | |
307 | new Geom2d_BSplineCurve(Poles, Knots, Mults, Deg); | |
308 | PCur2d = new Geom2d_TrimmedCurve( BS2d, Udeb, Ufin); | |
c22b52d6 | 309 | HPCur = new Geom2dAdaptor_Curve(PCur2d); |
7fd59977 | 310 | Only3d = Standard_True; |
311 | } | |
c22b52d6 | 312 | else if (HProjector->IsVIso(k, VIso)) { |
0797d9d3 | 313 | #ifdef OCCT_DEBUG |
04232180 | 314 | std::cout << "Projection of edge "<<i<<" on face "<<j; |
315 | std::cout << " is V-isoparametric"<<std::endl<<std::endl; | |
7fd59977 | 316 | #endif |
c22b52d6 | 317 | HProjector->D0(Udeb, Pdeb); |
318 | HProjector->D0(Ufin, Pfin); | |
7fd59977 | 319 | Poles(1) = Pdeb; |
320 | Poles(2) = Pfin; | |
321 | Knots(1) = Udeb; | |
322 | Knots(2) = Ufin; | |
323 | Handle(Geom2d_BSplineCurve) BS2d = | |
324 | new Geom2d_BSplineCurve(Poles, Knots, Mults, Deg); | |
325 | PCur2d = new Geom2d_TrimmedCurve(BS2d, Udeb, Ufin); | |
c22b52d6 | 326 | HPCur = new Geom2dAdaptor_Curve(PCur2d); |
7fd59977 | 327 | Only3d = Standard_True; |
328 | } | |
329 | else HPCur = HProjector; | |
330 | ||
331 | if((myWith3d == Standard_False || Elementary) && | |
c22b52d6 | 332 | (HProjector->MaxDistance(k) <= myTol3d) ) |
7fd59977 | 333 | Only2d = Standard_True; |
334 | ||
335 | if(Only2d && Only3d) { | |
336 | BRepLib_MakeEdge MKed(GeomAdaptor::MakeCurve(hcur->Curve()), | |
337 | Ufin, Udeb); | |
338 | prj = MKed.Edge(); | |
339 | BB.UpdateEdge(TopoDS::Edge(prj), | |
340 | PCur2d, | |
341 | TopoDS::Face(Faces->Value(j)), | |
342 | myTol3d); | |
343 | BB.UpdateVertex(TopExp::FirstVertex(TopoDS::Edge(prj)),myTol3d); | |
344 | BB.UpdateVertex(TopExp::LastVertex(TopoDS::Edge(prj)),myTol3d); | |
345 | } | |
346 | else { | |
0797d9d3 | 347 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 348 | InitChron(chr_approx); |
349 | #endif | |
f04de133 | 350 | Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d); |
351 | appr.Perform(myMaxSeg, myMaxDegree, myContinuity, Only3d, Only2d); | |
81f57d11 | 352 | |
353 | if (appr.MaxError3d() > 1.e3 * myTol3d) | |
354 | continue; | |
355 | ||
0797d9d3 | 356 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 357 | ResultChron(chr_approx,t_approx); |
358 | approx_count++; | |
359 | ||
04232180 | 360 | std::cout<<"Approximation.IsDone = "<<appr.IsDone()<<std::endl; |
7fd59977 | 361 | if(!Only2d) |
04232180 | 362 | std::cout<<"MaxError3d = "<<appr.MaxError3d()<<std::endl<<std::endl; |
7fd59977 | 363 | if(!Only3d) { |
04232180 | 364 | std::cout<<"MaxError2dU = "<<appr.MaxError2dU()<<std::endl; |
365 | std::cout<<"MaxError2dV = "<<appr.MaxError2dV()<<std::endl<<std::endl; | |
7fd59977 | 366 | } |
367 | #endif | |
368 | ||
369 | ||
370 | if(!Only3d) PCur2d = appr.Curve2d(); | |
371 | if(Only2d) { | |
372 | BRepLib_MakeEdge MKed(GeomAdaptor::MakeCurve(hcur->Curve()), | |
373 | Udeb, Ufin); | |
374 | prj = MKed.Edge(); | |
375 | } | |
376 | else { | |
0d969553 Y |
377 | // It is tested if the solution is not degenerated to set the |
378 | // flag on edge, one takes several points, checks if the cloud of | |
379 | // points has less diameter than the tolerance 3D | |
7fd59977 | 380 | Degenerated = Standard_True; |
381 | Standard_Real Dist; | |
a9dde4a3 | 382 | Handle(Geom_BSplineCurve) BS3d = appr.Curve3d(); |
7fd59977 | 383 | gp_Pnt P1(0.,0.,0.),PP; // skl : I change "P" to "PP" |
384 | Standard_Integer NbPoint,ii ; // skl : I change "i" to "ii" | |
385 | Standard_Real Par,DPar; | |
0d969553 Y |
386 | // start from 3 points to reject non degenerated edges |
387 | // very fast | |
7fd59977 | 388 | NbPoint =3; |
389 | DPar = (BS3d->LastParameter()-BS3d->FirstParameter())/(NbPoint-1); | |
390 | for (ii=0;ii<NbPoint;ii++) | |
391 | { | |
392 | Par=BS3d->FirstParameter()+ii*DPar; | |
393 | PP=BS3d->Value(Par); | |
394 | P1.SetXYZ(P1.XYZ() + PP.XYZ()/NbPoint); | |
395 | } | |
396 | for (ii=0;ii<NbPoint && Degenerated ;ii++) | |
397 | { | |
398 | Par=BS3d->FirstParameter()+ii*DPar; | |
399 | PP=BS3d->Value(Par); | |
400 | Dist=P1.Distance(PP); | |
401 | if(Dist > myTol3d) { | |
402 | Degenerated = Standard_False; | |
403 | break; | |
404 | } | |
405 | } | |
0d969553 | 406 | // if the test passes a more exact test with 10 points |
7fd59977 | 407 | if (Degenerated) { |
408 | P1.SetCoord(0.,0.,0.); | |
409 | NbPoint =10; | |
410 | DPar = (BS3d->LastParameter()-BS3d->FirstParameter())/(NbPoint-1); | |
411 | for (ii=0;ii<NbPoint;ii++) | |
412 | { | |
413 | Par=BS3d->FirstParameter()+ii*DPar; | |
414 | PP=BS3d->Value(Par); | |
415 | P1.SetXYZ(P1.XYZ() + PP.XYZ()/NbPoint); | |
416 | } | |
417 | for (ii=0;ii<NbPoint && Degenerated ;ii++) | |
418 | { | |
419 | Par=BS3d->FirstParameter()+ii*DPar; | |
420 | PP=BS3d->Value(Par); | |
421 | Dist=P1.Distance(PP); | |
422 | if(Dist > myTol3d) { | |
423 | Degenerated = Standard_False; | |
424 | break; | |
425 | } | |
426 | } | |
427 | } | |
428 | if (Degenerated) { | |
0797d9d3 | 429 | #ifdef OCCT_DEBUG |
04232180 | 430 | std::cout << "Projection of edge "<<i<<" on face "<<j; |
431 | std::cout << " is degenerated "<<std::endl<<std::endl; | |
7fd59977 | 432 | #endif |
433 | TopoDS_Vertex VV; | |
434 | BB.MakeVertex(VV); | |
435 | BB.UpdateVertex(VV,P1,myTol3d); | |
436 | BB.MakeEdge(TopoDS::Edge(prj)); | |
437 | BB.Add(TopoDS::Edge(prj),VV.Oriented(TopAbs_FORWARD)); | |
438 | BB.Add(TopoDS::Edge(prj),VV.Oriented(TopAbs_REVERSED)); | |
439 | BB.Degenerated(TopoDS::Edge(prj), Standard_True); | |
440 | } | |
441 | else { | |
442 | prj = BRepLib_MakeEdge(BS3d).Edge(); | |
443 | } | |
444 | } | |
445 | ||
446 | BB.UpdateEdge(TopoDS::Edge(prj), | |
447 | PCur2d, | |
448 | TopoDS::Face(Faces->Value(j)), | |
449 | appr.MaxError3d()); | |
450 | BB.UpdateVertex(TopExp::FirstVertex(TopoDS::Edge(prj)),appr.MaxError3d()); | |
451 | BB.UpdateVertex(TopExp::LastVertex(TopoDS::Edge(prj)),appr.MaxError3d()); | |
452 | if (Degenerated) { | |
453 | BB.Range(TopoDS::Edge(prj), | |
454 | TopoDS::Face(Faces->Value(j)), | |
455 | Udeb,Ufin); | |
456 | } | |
457 | } | |
458 | ||
459 | if(myFaceBounds) { | |
460 | // Trimming edges by face bounds | |
0d969553 | 461 | // if the solution is degenerated, use of BoolTool is avoided |
0797d9d3 | 462 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 463 | InitChron(chr_booltool); |
464 | #endif | |
8b956afe | 465 | if (!Degenerated) { |
466 | // Perform Boolean COMMON operation to get parts of projected edge | |
467 | // inside the face | |
977ad983 | 468 | BRepAlgoAPI_Section aSection(Faces->Value(j), prj); |
469 | if (aSection.IsDone()) { | |
470 | const TopoDS_Shape& aRC = aSection.Shape(); | |
8b956afe | 471 | // |
472 | TopExp_Explorer aExpE(aRC, TopAbs_EDGE); | |
473 | for (; aExpE.More(); aExpE.Next()) { | |
474 | const TopoDS_Shape& aE = aExpE.Current(); | |
475 | BB.Add(myRes, aE); | |
476 | myAncestorMap.Bind(aE, Edges->Value(i)); | |
477 | myCorresp.Bind(aE, Faces->Value(j)); | |
478 | } | |
479 | } | |
480 | else { | |
481 | // if the common operation has failed, try to classify the part | |
7fd59977 | 482 | BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)), |
483 | Precision::Confusion()); | |
484 | gp_Pnt2d Puv; | |
485 | Standard_Real f = PCur2d->FirstParameter(); | |
486 | Standard_Real l = PCur2d->LastParameter(); | |
487 | Standard_Real pmil = (f + l )/2; | |
488 | PCur2d->D0(pmil, Puv); | |
489 | TopAbs_State state; | |
490 | state = classifier.Perform(Puv); | |
491 | if(state == TopAbs_IN || state == TopAbs_ON) { | |
492 | BB.Add(myRes, prj); | |
493 | DescenList.Append(prj); | |
494 | myAncestorMap.Bind(prj, Edges->Value(i)); | |
495 | myCorresp.Bind(prj, Faces->Value(j)); | |
496 | } | |
497 | } | |
498 | } | |
499 | else { | |
0797d9d3 | 500 | #ifdef OCCT_DEBUG |
04232180 | 501 | std::cout << " BooleanOperations : no solution " << std::endl; |
7fd59977 | 502 | #endif |
503 | ||
504 | BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)), | |
505 | Precision::Confusion()); | |
506 | gp_Pnt2d Puv; | |
507 | Standard_Real f = PCur2d->FirstParameter(); | |
508 | Standard_Real l = PCur2d->LastParameter(); | |
509 | Standard_Real pmil = (f + l )/2; | |
510 | PCur2d->D0(pmil, Puv); | |
511 | TopAbs_State state; | |
512 | state = classifier.Perform(Puv); | |
513 | if(state == TopAbs_IN || state == TopAbs_ON) { | |
514 | BB.Add(myRes, prj); | |
515 | DescenList.Append(prj); | |
516 | myAncestorMap.Bind(prj, Edges->Value(i)); | |
517 | myCorresp.Bind(prj, Faces->Value(j)); | |
518 | } | |
0797d9d3 | 519 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 520 | ResultChron(chr_booltool,t_booltool); |
521 | booltool_count++; | |
522 | #endif | |
523 | } | |
524 | } | |
525 | else { | |
526 | BB.Add(myRes, prj); | |
527 | DescenList.Append(prj); | |
528 | myAncestorMap.Bind(prj, Edges->Value(i)); | |
529 | myCorresp.Bind(prj, Faces->Value(j)); | |
530 | } | |
531 | } | |
532 | } | |
533 | } | |
534 | myDescendants.Bind(Edges->Value(i), DescenList); | |
535 | } | |
0d969553 Y |
536 | // JPI : eventual wire creation is reported in a specific method |
537 | // BuilWire that can be called by the user. Otherwise, the | |
538 | // relations of map myAncestorMap, myCorresp will be lost. | |
7fd59977 | 539 | |
540 | if(YaVertexRes) BB.Add(myRes, VertexRes); | |
541 | ||
542 | myIsDone = Standard_True; | |
543 | ||
0797d9d3 | 544 | #ifdef OCCT_DEBUG_CHRONO |
7fd59977 | 545 | ResultChron(chr_total,t_total); |
546 | ||
04232180 | 547 | std::cout<<"Build - Total time : "<<t_total<<" includes:" <<std::endl; |
548 | std::cout<<"- Projection : "<<t_init<<std::endl; | |
549 | std::cout<<" -- Initial point search : "<<t_init_point<<std::endl; | |
550 | std::cout<<" -- DichoBound search : "<<t_dicho_bound<<std::endl; | |
551 | std::cout<<"- Approximation : "<<t_approx<<std::endl; | |
552 | std::cout<<"- Boolean operation : "<<t_booltool<<std::endl; | |
553 | std::cout<<"- Rest of time : "<<t_total-(t_init + t_approx + t_booltool )<<std::endl<<std::endl; | |
7fd59977 | 554 | if (init_count != 0) |
555 | t_init /= init_count; | |
556 | if (init_point_count != 0) | |
557 | t_init_point /= init_point_count; | |
558 | if (dicho_bound_count != 0) | |
559 | t_dicho_bound /= dicho_bound_count; | |
560 | if (approx_count != 0) | |
561 | t_approx /= approx_count; | |
562 | if (booltool_count != 0) | |
563 | t_booltool /= booltool_count; | |
564 | ||
04232180 | 565 | std::cout<<"Unitary average time : "<<std::endl; |
566 | std::cout<<"- Projection : "<<t_init<<std::endl; | |
567 | std::cout<<" -- Initial point search: "<<t_init_point<<std::endl; | |
568 | std::cout<<" -- DichoBound search : "<<t_dicho_bound<<std::endl; | |
569 | std::cout<<"- Approximation : "<<t_approx<<std::endl; | |
570 | std::cout<<"- Boolean operation :"<<t_booltool<<std::endl; | |
571 | std::cout<<std::endl<<"Number of initial point computations is "<<init_point_count<<std::endl<<std::endl; | |
7fd59977 | 572 | #endif |
573 | } | |
574 | ||
575 | //======================================================================= | |
576 | //function : IsDone | |
577 | //purpose : | |
578 | //======================================================================= | |
579 | ||
580 | Standard_Boolean BRepAlgo_NormalProjection::IsDone() const | |
581 | { | |
582 | return myIsDone; | |
583 | } | |
584 | ||
585 | //======================================================================= | |
586 | //function : Projection | |
587 | //purpose : | |
588 | //======================================================================= | |
589 | ||
590 | const TopoDS_Shape& BRepAlgo_NormalProjection::Projection() const | |
591 | { | |
592 | return myRes; | |
593 | } | |
594 | ||
595 | //======================================================================= | |
596 | //function : Ancestor | |
597 | //purpose : | |
598 | //======================================================================= | |
599 | ||
600 | const TopoDS_Shape& BRepAlgo_NormalProjection::Ancestor(const TopoDS_Edge& E) const | |
601 | { | |
602 | return myAncestorMap.Find(E); | |
603 | } | |
604 | ||
605 | //======================================================================= | |
606 | //function : Couple | |
607 | //purpose : | |
608 | //======================================================================= | |
609 | ||
610 | const TopoDS_Shape& BRepAlgo_NormalProjection::Couple(const TopoDS_Edge& E) const | |
611 | { | |
612 | return myCorresp.Find(E); | |
613 | } | |
614 | ||
615 | //======================================================================= | |
616 | //function : Generated | |
617 | //purpose : | |
618 | //======================================================================= | |
619 | ||
620 | const TopTools_ListOfShape& BRepAlgo_NormalProjection::Generated(const TopoDS_Shape& S) | |
621 | { | |
622 | return myDescendants.Find(S); | |
623 | } | |
624 | ||
625 | //======================================================================= | |
626 | //function : IsElementary | |
627 | //purpose : | |
628 | //======================================================================= | |
629 | ||
630 | Standard_Boolean BRepAlgo_NormalProjection::IsElementary(const Adaptor3d_Curve& C) const | |
631 | { | |
632 | GeomAbs_CurveType type; | |
633 | type = C.GetType(); | |
634 | switch(type) { | |
635 | case GeomAbs_Line: | |
636 | case GeomAbs_Circle: | |
637 | case GeomAbs_Ellipse: | |
638 | case GeomAbs_Hyperbola: | |
639 | case GeomAbs_Parabola: return Standard_True; | |
640 | default: return Standard_False; | |
641 | } | |
642 | } | |
643 | //======================================================================= | |
644 | //function : BuildWire | |
645 | //purpose : | |
646 | //======================================================================= | |
647 | ||
648 | Standard_Boolean BRepAlgo_NormalProjection::BuildWire(TopTools_ListOfShape& ListOfWire) const | |
649 | { | |
650 | TopExp_Explorer ExpOfWire, ExpOfShape; | |
651 | Standard_Boolean IsWire=Standard_False; | |
652 | ExpOfShape.Init(myRes, TopAbs_EDGE); | |
653 | if(ExpOfShape.More()) | |
654 | { | |
655 | TopTools_ListOfShape List; | |
656 | ||
657 | for ( ; ExpOfShape.More(); ExpOfShape.Next()) | |
658 | { | |
659 | const TopoDS_Shape& CurE = ExpOfShape.Current(); | |
660 | List.Append(CurE); | |
661 | } | |
662 | BRepLib_MakeWire MW; | |
663 | MW.Add(List); | |
664 | if (MW.IsDone()) | |
665 | { | |
666 | const TopoDS_Shape& Wire = MW.Shape(); | |
0d969553 Y |
667 | // If the resulting wire contains the same edge as at the beginning OK |
668 | // otherwise the result really consists of several wires. | |
7fd59977 | 669 | TopExp_Explorer exp2(Wire,TopAbs_EDGE); |
670 | Standard_Integer NbEdges = 0; | |
671 | for (;exp2.More(); exp2.Next()) NbEdges++; | |
672 | if ( NbEdges == List.Extent()) | |
673 | { | |
674 | ListOfWire.Append(Wire); | |
675 | IsWire = Standard_True; | |
676 | } | |
677 | } | |
678 | } | |
679 | return IsWire; | |
680 | } |