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