4e57c75e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
4e57c75e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
4e57c75e |
5 | // |
973c2be1 |
6 | // This library is free software; you can redistribute it and / or modify it |
7 | // under the terms of the GNU Lesser General Public version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
4e57c75e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
4e57c75e |
14 | |
15 | #include <BOPTools_AlgoTools3D.ixx> |
16 | |
17 | #include <TopExp.hxx> |
18 | #include <TopExp_Explorer.hxx> |
19 | |
20 | #include <TopoDS.hxx> |
21 | #include <TopoDS_Shape.hxx> |
22 | #include <TopoDS_Edge.hxx> |
23 | #include <TopoDS_Face.hxx> |
24 | #include <TopoDS_Vertex.hxx> |
25 | |
26 | #include <BOPCol_IndexedMapOfShape.hxx> |
27 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
28 | |
29 | #include <BRep_Builder.hxx> |
30 | #include <BRep_Tool.hxx> |
31 | #include <BRepTools.hxx> |
32 | #include <BRepAdaptor_Surface.hxx> |
33 | |
34 | #include <gp_Vec2d.hxx> |
35 | #include <gp_Pnt2d.hxx> |
36 | #include <gp_Lin2d.hxx> |
37 | #include <gp_Dir2d.hxx> |
38 | #include <gp_Vec.hxx> |
39 | #include <gp_Dir.hxx> |
40 | #include <gp_Pln.hxx> |
41 | |
42 | #include <Geom2d_Curve.hxx> |
43 | #include <Geom2d_TrimmedCurve.hxx> |
44 | #include <Geom2d_Line.hxx> |
45 | |
46 | #include <Geom_Curve.hxx> |
47 | #include <Geom_Surface.hxx> |
48 | #include <Geom_BSplineSurface.hxx> |
49 | #include <Geom_BezierSurface.hxx> |
50 | |
51 | #include <GeomAdaptor_Surface.hxx> |
52 | |
53 | #include <IntTools_Tools.hxx> |
54 | |
55 | #include <BOPTools_AlgoTools2D.hxx> |
56 | |
57 | #include <GProp_GProps.hxx> |
58 | #include <BRepGProp.hxx> |
59 | #include <BRepBndLib.hxx> |
60 | #include <Bnd_Box.hxx> |
61 | #include <gp_Cylinder.hxx> |
62 | #include <BRep_TVertex.hxx> |
63 | #include <BRep_ListIteratorOfListOfPointRepresentation.hxx> |
64 | #include <BRep_PointRepresentation.hxx> |
65 | #include <BRep_TEdge.hxx> |
66 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
67 | #include <BRep_CurveRepresentation.hxx> |
68 | #include <BRep_TFace.hxx> |
69 | #include <Poly_Triangulation.hxx> |
70 | #include <BRep_Builder.hxx> |
71 | #include <BOPInt_Context.hxx> |
72 | #include <Geom2dAdaptor_Curve.hxx> |
73 | #include <Geom2dHatch_Hatcher.hxx> |
74 | #include <HatchGen_Domain.hxx> |
75 | |
76 | static void Add(const TopoDS_Shape& aS, |
77 | BOPCol_IndexedMapOfShape& myShapes, |
78 | Standard_Boolean& bHasGeometry); |
79 | static |
80 | Standard_Boolean HasGeometry(const TopoDS_Shape& aS); |
81 | |
82 | //======================================================================= |
83 | //function : DoSplitSEAMOnFace |
84 | //purpose : |
85 | //======================================================================= |
86 | void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit, |
fe343049 |
87 | const TopoDS_Face& aF) |
4e57c75e |
88 | { |
1d47d8d0 |
89 | Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft = Standard_False; |
0929d0ef |
90 | Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU/*=1.e-7*/, anU1, |
91 | anV, dV/*=1.e-7*/, anV1; |
4e57c75e |
92 | Standard_Real aScPr; |
93 | gp_Pnt2d aP2D; |
94 | gp_Vec2d aVec2D; |
95 | Handle(Geom2d_Curve) aTmpC1, aTmpC2; |
96 | Handle(Geom2d_Curve) C2D1; |
97 | Handle(Geom2d_Line) aLD1; |
98 | Handle(Geom_Surface) aS; |
99 | BRep_Builder BB; |
100 | TopoDS_Edge aSp; |
101 | // |
102 | aSp=aSplit; |
103 | aSp.Orientation(TopAbs_FORWARD); |
4e57c75e |
104 | aTol=BRep_Tool::Tolerance(aSp); |
fe343049 |
105 | // |
4e57c75e |
106 | aS=BRep_Tool::Surface(aF); |
107 | bIsUPeriodic=aS->IsUPeriodic(); |
fe343049 |
108 | bIsVPeriodic=aS->IsVPeriodic(); |
109 | // |
110 | anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.; |
111 | anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.; |
112 | // |
113 | if (!bIsUPeriodic && !bIsVPeriodic) { |
114 | Standard_Boolean bIsUClosed, bIsVClosed; |
1d47d8d0 |
115 | Standard_Real aUmin = 0., aUmax = 0., aVmin = 0., aVmax = 0.; |
4e57c75e |
116 | Handle(Geom_BSplineSurface) aBS; |
117 | Handle(Geom_BezierSurface) aBZ; |
118 | // |
119 | bIsUClosed=Standard_False; |
fe343049 |
120 | bIsVClosed=Standard_False; |
4e57c75e |
121 | aBS=Handle(Geom_BSplineSurface)::DownCast(aS); |
122 | aBZ=Handle(Geom_BezierSurface) ::DownCast(aS); |
123 | // |
124 | if (!aBS.IsNull()) { |
125 | bIsUClosed=aBS->IsUClosed(); |
fe343049 |
126 | bIsVClosed=aBS->IsVClosed(); |
4e57c75e |
127 | aBS->Bounds(aUmin, aUmax, aVmin, aVmax); |
128 | } |
129 | else if (!aBZ.IsNull()) { |
130 | bIsUClosed=aBZ->IsUClosed(); |
fe343049 |
131 | bIsVClosed=aBZ->IsVClosed(); |
4e57c75e |
132 | aBZ->Bounds(aUmin, aUmax, aVmin, aVmax); |
133 | } |
fe343049 |
134 | if (!bIsUClosed && !bIsVClosed) { |
4e57c75e |
135 | return; |
136 | } |
137 | // |
fe343049 |
138 | if (bIsUClosed) { |
139 | anUPeriod=aUmax-aUmin; |
140 | } |
141 | if (bIsVClosed) { |
142 | anVPeriod=aVmax-aVmin; |
143 | } |
4e57c75e |
144 | } |
145 | // |
146 | C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b); |
147 | // |
148 | aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b); |
149 | C2D1->D1(aT, aP2D, aVec2D); |
fe343049 |
150 | gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.); |
4e57c75e |
151 | // |
fe343049 |
152 | anU=aP2D.X(); |
153 | anV=aP2D.Y(); |
4e57c75e |
154 | // |
fe343049 |
155 | anU1=anU; |
156 | anV1=anV; |
4e57c75e |
157 | // |
0929d0ef |
158 | GeomAdaptor_Surface aGAS(aS); |
159 | dU = aGAS.UResolution(aTol); |
160 | dV = aGAS.VResolution(aTol); |
161 | // |
fe343049 |
162 | if (anUPeriod > 0.){ |
163 | if (fabs (anU) < dU) { |
164 | bIsLeft=Standard_True; |
165 | anU1=anU+anUPeriod; |
166 | } |
167 | else if (fabs (anU-anUPeriod) < dU) { |
168 | bIsLeft=Standard_False; |
169 | anU1=anU-anUPeriod; |
170 | } |
4e57c75e |
171 | } |
fe343049 |
172 | // |
173 | if (anVPeriod > 0.) { |
174 | if (fabs (anV) < dV) { |
175 | bIsLeft=Standard_True; |
176 | anV1=anV+anVPeriod; |
177 | } |
178 | else if (fabs (anV-anVPeriod) < dV) { |
179 | bIsLeft=Standard_False; |
180 | anV1=anV-anVPeriod; |
181 | } |
4e57c75e |
182 | } |
fe343049 |
183 | // |
184 | if (anU1==anU && anV1==anV) { |
4e57c75e |
185 | return; |
186 | } |
187 | // |
fe343049 |
188 | aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY; |
189 | // |
4e57c75e |
190 | aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy()); |
191 | Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b); |
fe343049 |
192 | // |
4e57c75e |
193 | aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy()); |
194 | Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b); |
fe343049 |
195 | gp_Vec2d aTrV(anU1-anU, anV1-anV); |
4e57c75e |
196 | aC2->Translate(aTrV); |
197 | // |
198 | if (!bIsLeft) { |
199 | if (aScPr<0.) { |
200 | BB.UpdateEdge(aSp, aC2, aC1, aF, aTol); |
201 | } |
202 | else { |
203 | BB.UpdateEdge(aSp, aC1, aC2, aF, aTol); |
204 | } |
205 | } |
206 | else { |
207 | if (aScPr<0.) { |
208 | BB.UpdateEdge(aSp, aC1, aC2, aF, aTol); |
209 | } |
210 | else { |
211 | BB.UpdateEdge(aSp, aC2, aC1, aF, aTol); |
212 | } |
213 | } |
4e57c75e |
214 | } |
215 | |
216 | //======================================================================= |
217 | //function : GetNormalToFaceOnEdge |
218 | //purpose : |
219 | //======================================================================= |
220 | void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE, |
221 | const TopoDS_Face& aF, |
222 | gp_Dir& aDNF) |
223 | { |
224 | Standard_Real aT, aT1, aT2; |
225 | |
226 | BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); |
227 | aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); |
228 | |
229 | BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF); |
230 | |
231 | if (aF.Orientation()==TopAbs_REVERSED){ |
232 | aDNF.Reverse(); |
233 | } |
234 | } |
235 | |
236 | //======================================================================= |
237 | //function : GetNormalToFaceOnEdge |
238 | //purpose : |
239 | //======================================================================= |
240 | void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE, |
241 | const TopoDS_Face& aF1, |
242 | const Standard_Real aT, |
243 | gp_Dir& aDNF1) |
244 | { |
245 | Standard_Real U, V, aTolPC; |
246 | gp_Pnt2d aP2D; |
247 | gp_Pnt aP; |
248 | gp_Vec aD1U, aD1V; |
249 | |
250 | Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1); |
251 | |
252 | Handle(Geom2d_Curve)aC2D1; |
253 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC); |
254 | |
255 | aC2D1->D0(aT, aP2D); |
256 | U=aP2D.X(); |
257 | V=aP2D.Y(); |
258 | |
259 | aS1->D1(U, V, aP, aD1U, aD1V); |
260 | gp_Dir aDD1U(aD1U); |
261 | gp_Dir aDD1V(aD1V); |
262 | |
263 | aDNF1=aDD1U^aDD1V; |
264 | } |
265 | |
266 | //======================================================================= |
267 | //function : SenseFlag |
268 | //purpose : |
269 | //======================================================================= |
270 | Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1, |
271 | const gp_Dir& aDNF2) |
272 | { |
273 | Standard_Boolean bIsDirsCoinside; |
274 | bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2); |
275 | if (!bIsDirsCoinside) { |
276 | return 0; |
277 | } |
278 | |
279 | Standard_Real aScPr; |
280 | |
281 | aScPr=aDNF1*aDNF2; |
282 | if (aScPr<0.) { |
283 | return -1; |
284 | } |
285 | else if (aScPr>0.) { |
286 | return 1; |
287 | } |
288 | return -1; |
289 | } |
290 | |
291 | //======================================================================= |
292 | //function : GetNormalToSurface |
293 | //purpose : |
294 | //======================================================================= |
295 | Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface (const Handle(Geom_Surface)& aS, |
296 | const Standard_Real U, |
297 | const Standard_Real V, |
298 | gp_Dir& aDNS) |
299 | { |
300 | Standard_Boolean bFlag; |
301 | |
302 | gp_Pnt aP; |
303 | gp_Vec aD1U, aD1V; |
304 | |
305 | aS->D1(U, V, aP, aD1U, aD1V); |
306 | |
307 | gp_Dir aDD1U(aD1U); |
308 | gp_Dir aDD1V(aD1V); |
309 | |
310 | bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U); |
311 | if (!bFlag) { |
312 | return bFlag; |
313 | } |
314 | |
315 | aDNS=aDD1U^aDD1V; |
316 | return bFlag; |
317 | } |
318 | |
319 | //======================================================================= |
320 | //function : GetApproxNormalToFaceOnEdge |
321 | //purpose : |
322 | //======================================================================= |
323 | |
324 | void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(const TopoDS_Edge& aE, |
325 | const TopoDS_Face& aF, |
326 | const Standard_Real aT, |
327 | gp_Pnt& aPNear, |
328 | gp_Dir& aDNF, |
329 | Standard_Real aDt2D) |
330 | { |
331 | Standard_Real aFirst, aLast; |
332 | Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); |
333 | |
334 | if (aC2D.IsNull()) { |
335 | return; |
336 | } |
337 | gp_Pnt2d aPx2DNear; |
338 | PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear); |
339 | Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); |
340 | |
341 | BOPTools_AlgoTools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); |
342 | |
343 | if (aF.Orientation()==TopAbs_REVERSED){ |
344 | aDNF.Reverse(); |
345 | } |
346 | } |
347 | |
348 | |
349 | //======================================================================= |
350 | //function : GetApproxNormalToFaceOnEdge |
351 | //purpose : |
352 | //======================================================================= |
353 | void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE, |
354 | const TopoDS_Face& aF, |
355 | const Standard_Real aT, |
356 | gp_Pnt& aPNear, |
357 | gp_Dir& aDNF, |
358 | Handle(BOPInt_Context)& theContext) |
359 | { |
360 | Standard_Real aFirst, aLast; |
361 | Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); |
362 | |
363 | if (aC2D.IsNull()) { |
364 | return; |
365 | } |
366 | //gp_Pnt aPNear; |
367 | gp_Pnt2d aPx2DNear; |
368 | BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, aPx2DNear, aPNear, theContext); |
369 | |
370 | Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); |
371 | |
372 | BOPTools_AlgoTools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); |
373 | |
374 | if (aF.Orientation()==TopAbs_REVERSED){ |
375 | aDNF.Reverse(); |
376 | } |
377 | } |
378 | |
379 | //======================================================================= |
380 | //function : PointNearEdge |
381 | //purpose : |
382 | //======================================================================= |
383 | void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, |
384 | const TopoDS_Face& aF, |
385 | const Standard_Real aT, |
386 | const Standard_Real aDt2D, |
387 | gp_Pnt2d& aPx2DNear, |
388 | gp_Pnt& aPxNear) |
389 | { |
390 | Standard_Real aFirst, aLast, aETol, aFTol, transVal; |
391 | GeomAbs_SurfaceType aTS; |
392 | Handle(Geom2d_Curve) aC2D; |
393 | Handle(Geom_Surface) aS; |
394 | // |
395 | aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); |
396 | if (aC2D.IsNull()) { |
397 | aPx2DNear.SetCoord (99., 99); |
398 | return; |
399 | } |
400 | // |
401 | aS=BRep_Tool::Surface(aF); |
402 | // |
403 | gp_Pnt2d aPx2D; |
404 | gp_Vec2d aVx2D; |
405 | aC2D->D1 (aT, aPx2D, aVx2D); |
406 | gp_Dir2d aDx2D(aVx2D); |
407 | |
408 | gp_Dir2d aDP; |
409 | aDP.SetCoord (-aDx2D.Y(), aDx2D.X()); |
410 | |
411 | if (aE.Orientation()==TopAbs_REVERSED){ |
412 | aDP.Reverse(); |
413 | } |
414 | |
415 | if (aF.Orientation()==TopAbs_REVERSED) { |
416 | aDP.Reverse(); |
417 | } |
418 | // |
419 | aETol = BRep_Tool::Tolerance(aE); |
420 | aFTol = BRep_Tool::Tolerance(aF); |
f4ea2ca6 |
421 | // NPAL19220 |
4e57c75e |
422 | GeomAdaptor_Surface aGAS(aS); |
423 | aTS=aGAS.GetType(); |
424 | if (aTS==GeomAbs_BSplineSurface) { |
425 | if (aETol > 1.e-5) { |
426 | aFTol=aETol; |
427 | } |
428 | } |
429 | if( aETol > 1.e-5 || aFTol > 1.e-5 ) { |
430 | //if( aETol > 1.e-5 && aFTol > 1.e-5 ) { |
431 | //pkv/103/D7 |
432 | if(aTS!=GeomAbs_Sphere) { |
433 | gp_Vec2d transVec( aDP ); |
434 | transVal = aDt2D + aETol + aFTol; |
435 | if (aTS==GeomAbs_Cylinder) {// pkv/909/F8 |
436 | Standard_Real aR, dT; |
437 | // |
438 | gp_Cylinder aCyl=aGAS.Cylinder(); |
439 | aR=aCyl.Radius(); |
440 | dT=1.-transVal/aR; |
441 | if (dT>=-1 && dT<=1) { |
442 | dT=acos(dT); |
443 | transVal=dT; |
444 | } |
445 | } |
446 | // |
447 | transVec.Multiply(transVal); |
448 | aPx2DNear = aPx2D.Translated( transVec ); |
449 | } |
450 | else { |
451 | aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y()); |
452 | } |
453 | } |
454 | else { |
455 | aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y()); |
456 | } |
457 | // |
458 | aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear); |
459 | } |
460 | |
461 | //======================================================================= |
462 | //function : PointNearEdge |
463 | //purpose : |
464 | //======================================================================= |
f4ea2ca6 |
465 | void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, |
466 | const TopoDS_Face& aF, |
467 | const Standard_Real aT, |
468 | gp_Pnt2d& aPx2DNear, |
469 | gp_Pnt& aPxNear, |
470 | Handle(BOPInt_Context)& theContext) |
4e57c75e |
471 | { |
f4ea2ca6 |
472 | Standard_Real aTolE, aTolF, dTx, dT2D; |
473 | Handle(Geom_Surface) aS; |
474 | GeomAdaptor_Surface aGAS; |
4e57c75e |
475 | // |
f4ea2ca6 |
476 | dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5; |
477 | // |
478 | aS = BRep_Tool::Surface(aF); |
479 | aGAS.Load(aS); |
4e57c75e |
480 | if (aGAS.GetType()==GeomAbs_Cylinder || |
481 | aGAS.GetType()==GeomAbs_Sphere) { |
f4ea2ca6 |
482 | dT2D=10.*dT2D; |
483 | } |
484 | // |
4e57c75e |
485 | aTolE = BRep_Tool::Tolerance(aE); |
486 | aTolF = BRep_Tool::Tolerance(aF); |
f4ea2ca6 |
487 | dTx = 2.*(aTolE + aTolF); |
488 | if (dTx > dT2D) { |
489 | dT2D=dTx; |
490 | } |
491 | // |
492 | BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, dT2D, aPx2DNear, aPxNear); |
4e57c75e |
493 | if (!theContext->IsPointInOnFace(aF, aPx2DNear)) { |
f4ea2ca6 |
494 | Standard_Integer iErr; |
495 | Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh; |
4e57c75e |
496 | gp_Pnt aP; |
497 | gp_Pnt2d aP2d; |
4e57c75e |
498 | // |
f4ea2ca6 |
499 | BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2); |
500 | // |
501 | dU=aU2-aU1; |
502 | dV=aV2-aV1; |
503 | // |
504 | dTresh=1.e-4; |
505 | if (dT2D > dTresh) { |
506 | dTresh=dT2D; |
507 | } |
508 | // |
509 | if (dU < dTresh || dV < dTresh) { |
510 | iErr = BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2d, theContext); |
4e57c75e |
511 | if (!iErr) { |
512 | aPxNear = aP; |
513 | aPx2DNear = aP2d; |
514 | } |
515 | } |
516 | } |
517 | } |
518 | |
519 | //======================================================================= |
520 | // function: PointNearEdge |
521 | // purpose: |
522 | //======================================================================= |
523 | void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, |
524 | const TopoDS_Face& aF, |
525 | gp_Pnt2d& aPInFace2D, |
526 | gp_Pnt& aPInFace, |
527 | Handle(BOPInt_Context)& theContext) |
528 | { |
529 | Standard_Real aT, aT1, aT2; |
530 | // |
531 | // 1. |
532 | BRep_Tool::Range(aE, aT1, aT2); |
533 | aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); |
534 | // |
535 | // 2. a Point inside Face near aPOnEdge aPInFace; |
536 | TopoDS_Face aFF=aF; |
537 | TopoDS_Edge aERight; |
538 | aFF.Orientation(TopAbs_FORWARD); |
539 | BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight); |
540 | |
541 | BOPTools_AlgoTools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace, theContext); |
542 | } |
543 | |
544 | //======================================================================= |
545 | //function : MinStepIn2d |
546 | //purpose : |
547 | //======================================================================= |
548 | Standard_Real BOPTools_AlgoTools3D::MinStepIn2d() |
549 | { |
550 | Standard_Real dt=1.e-5; |
551 | return dt; |
552 | } |
553 | |
554 | //======================================================================= |
555 | //function : IsEmptyShape |
556 | //purpose : |
557 | //======================================================================= |
558 | Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape(const TopoDS_Shape& aS) |
559 | { |
560 | Standard_Boolean bHasGeometry=Standard_False; |
561 | // |
562 | BOPCol_IndexedMapOfShape myShapes; |
563 | // |
564 | Add(aS, myShapes, bHasGeometry); |
565 | |
566 | return !bHasGeometry; |
567 | } |
568 | |
569 | //======================================================================= |
570 | //function : Add |
571 | //purpose : |
572 | //======================================================================= |
573 | void Add(const TopoDS_Shape& aS, |
574 | BOPCol_IndexedMapOfShape& myShapes, |
575 | Standard_Boolean& bHasGeometry) |
576 | { |
577 | Standard_Integer anIndex; |
578 | // |
579 | if (bHasGeometry) { |
580 | return; |
581 | } |
582 | // |
583 | if (aS.IsNull()) { |
584 | return; |
585 | } |
586 | // |
587 | TopoDS_Shape aSx = aS; |
588 | // |
589 | anIndex=myShapes.FindIndex(aSx); |
590 | if (!anIndex) { |
591 | bHasGeometry=HasGeometry (aSx); |
592 | if (bHasGeometry) { |
593 | return; |
594 | } |
595 | // |
596 | TopoDS_Iterator anIt(aSx, Standard_False, Standard_False); |
597 | for(; anIt.More(); anIt.Next()) { |
598 | const TopoDS_Shape& aSy=anIt.Value(); |
599 | Add(aSy, myShapes, bHasGeometry); |
600 | // |
601 | if (bHasGeometry) { |
602 | return; |
603 | } |
604 | // |
605 | myShapes.Add(aSx); |
606 | } |
607 | } |
608 | } |
609 | |
610 | //======================================================================= |
611 | //function : HasGeometry |
612 | //purpose : |
613 | //======================================================================= |
614 | Standard_Boolean HasGeometry(const TopoDS_Shape& aS) |
615 | { |
616 | Standard_Boolean bHasGeometry=Standard_True; |
617 | TopAbs_ShapeEnum aType= aS.ShapeType(); |
618 | |
619 | if (aType == TopAbs_VERTEX) { |
620 | |
621 | Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(aS.TShape()); |
622 | BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points()); |
623 | |
624 | while (itrp.More()) { |
625 | const Handle(BRep_PointRepresentation)& PR = itrp.Value(); |
626 | |
627 | if (PR->IsPointOnCurve()) { |
628 | return bHasGeometry; |
629 | } |
630 | |
631 | else if (PR->IsPointOnCurveOnSurface()) { |
632 | return bHasGeometry; |
633 | } |
634 | |
635 | else if (PR->IsPointOnSurface()) { |
636 | return bHasGeometry; |
637 | } |
638 | itrp.Next(); |
639 | } |
640 | } |
641 | |
642 | // |
643 | else if (aType == TopAbs_EDGE) { |
644 | Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape()); |
645 | BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves()); |
646 | |
647 | while (itrc.More()) { |
648 | const Handle(BRep_CurveRepresentation)& CR = itrc.Value(); |
649 | if (CR->IsCurve3D()) { |
650 | if (!CR->Curve3D().IsNull()) { |
651 | return bHasGeometry; |
652 | } |
653 | } |
654 | else if (CR->IsCurveOnSurface()) { |
655 | return bHasGeometry; |
656 | } |
657 | else if (CR->IsRegularity()) { |
658 | return bHasGeometry; |
659 | } |
660 | else if (!CR->Polygon3D().IsNull()) { |
661 | return bHasGeometry; |
662 | } |
663 | else if (CR->IsPolygonOnTriangulation()) { |
664 | return bHasGeometry; |
665 | } |
666 | else if (CR->IsPolygonOnSurface()) { |
667 | return bHasGeometry; |
668 | } |
669 | itrc.Next(); |
670 | } |
671 | } |
672 | // |
673 | else if (aType == TopAbs_FACE) { |
674 | Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape()); |
675 | if (!TF->Surface().IsNull()) { |
676 | return bHasGeometry; |
677 | } |
678 | Handle(Poly_Triangulation) Tr = TF->Triangulation(); |
679 | if (!Tr.IsNull()) { |
680 | return bHasGeometry; |
681 | } |
682 | } |
683 | |
684 | return !bHasGeometry; |
685 | } |
686 | |
687 | |
688 | //======================================================================= |
689 | //function : OrientEdgeOnFace |
690 | //purpose : |
691 | //======================================================================= |
692 | void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE, |
693 | const TopoDS_Face& aF, |
694 | TopoDS_Edge& aERight) |
695 | { |
696 | if (BRep_Tool::IsClosed(aE, aF)) { |
697 | aERight=aE; |
698 | aERight.Orientation(aE.Orientation()); |
699 | |
700 | Standard_Integer iFoundCount = 0; |
701 | TopoDS_Edge anEdge = aE; |
702 | TopExp_Explorer anExp(aF, TopAbs_EDGE); |
703 | |
704 | for (; anExp.More(); anExp.Next()) { |
705 | const TopoDS_Shape& aSS=anExp.Current(); |
706 | |
707 | if (aSS.IsSame(aE)) { |
708 | anEdge = TopoDS::Edge(aSS); |
709 | iFoundCount++; |
710 | } |
711 | } |
712 | |
713 | if(iFoundCount == 1) { |
714 | aERight = anEdge; |
715 | } |
716 | return; |
717 | } |
718 | |
719 | TopExp_Explorer anExp(aF, TopAbs_EDGE); |
720 | for (; anExp.More(); anExp.Next()) { |
721 | const TopoDS_Shape& aSS=anExp.Current(); |
722 | if (aSS.IsSame(aE)) { |
723 | aERight=aE; |
724 | aERight.Orientation(aSS.Orientation()); |
725 | return; |
726 | } |
727 | } |
728 | aERight=aE; |
729 | aERight.Orientation(aE.Orientation()); |
730 | } |
731 | |
732 | //======================================================================= |
733 | //function : PointInFace |
734 | //purpose : |
735 | //======================================================================= |
736 | Standard_Integer BOPTools_AlgoTools3D::PointInFace(const TopoDS_Face& aF, |
737 | gp_Pnt& theP, |
738 | gp_Pnt2d& theP2D, |
739 | Handle(BOPInt_Context)& theContext) |
740 | { |
741 | Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; |
3ed30348 |
742 | Standard_Integer iErr, aIx, aNbDomains; |
4e57c75e |
743 | Standard_Real aUMin, aUMax, aVMin, aVMax; |
96a95605 |
744 | Standard_Real aVx = 0., aUx, aV1, aV2; |
4e57c75e |
745 | gp_Dir2d aD2D (0., 1.); |
746 | gp_Pnt2d aP2D; |
747 | gp_Pnt aPx; |
748 | Handle(Geom2d_Curve) aC2D; |
749 | Handle(Geom2d_Line) aL2D; |
750 | Handle(Geom_Surface) aS; |
751 | TopoDS_Face aFF; |
752 | // |
753 | Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF); |
754 | // |
755 | iErr=0; |
4e57c75e |
756 | // |
757 | aFF=aF; |
758 | aFF.Orientation (TopAbs_FORWARD); |
759 | // |
760 | aS=BRep_Tool::Surface(aFF); |
761 | BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); |
762 | // |
763 | aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax); |
764 | aP2D.SetCoord(aUx, 0.); |
765 | aL2D=new Geom2d_Line (aP2D, aD2D); |
766 | Geom2dAdaptor_Curve aHCur(aL2D); |
767 | // |
768 | aIx=aHatcher.AddHatching(aHCur) ; |
769 | // |
770 | aHatcher.Trim(); |
771 | bIsDone=aHatcher.TrimDone(aIx); |
772 | if (!bIsDone) { |
773 | iErr=1; |
774 | return iErr; |
775 | } |
776 | // |
777 | aHatcher.ComputeDomains(aIx); |
778 | bIsDone=aHatcher.IsDone(aIx); |
779 | if (!bIsDone) { |
780 | iErr=2; |
781 | return iErr; |
782 | } |
783 | // |
784 | aNbDomains=aHatcher.NbDomains(aIx); |
3ed30348 |
785 | if (aNbDomains > 0) { |
786 | const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1) ; |
4e57c75e |
787 | bHasFirstPoint=aDomain.HasFirstPoint(); |
788 | if (!bHasFirstPoint) { |
789 | iErr=3; |
790 | return iErr; |
791 | } |
792 | // |
793 | aV1=aDomain.FirstPoint().Parameter(); |
794 | // |
795 | bHasSecondPoint=aDomain.HasSecondPoint(); |
796 | if (!bHasSecondPoint) { |
797 | iErr=4; |
798 | return iErr; |
799 | } |
800 | // |
801 | aV2=aDomain.SecondPoint().Parameter(); |
802 | // |
803 | aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); |
804 | // |
3ed30348 |
805 | } |
806 | else { |
807 | iErr=2; |
808 | return iErr; |
4e57c75e |
809 | } |
810 | // |
811 | aS->D0(aUx, aVx, aPx); |
812 | // |
813 | theP2D.SetCoord(aUx, aVx); |
814 | theP=aPx; |
815 | // |
816 | return iErr; |
817 | } |