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