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