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