d7223c76 |
1 | // Copyright (c) 2013 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
18 | |
19 | #include <Hatch_Hatcher.hxx> |
20 | #include <Graphic3d_Group.hxx> |
21 | #include <gp_Pnt.hxx> |
22 | #include <Prs3d_IsoAspect.hxx> |
23 | #include <Adaptor3d_IsoCurve.hxx> |
24 | #include <Bnd_Box2d.hxx> |
25 | #include <BndLib_Add2dCurve.hxx> |
26 | #include <Precision.hxx> |
27 | #include <GeomAdaptor_Curve.hxx> |
28 | #include <Geom_Curve.hxx> |
29 | #include <GeomAbs_SurfaceType.hxx> |
30 | #include <Geom_Surface.hxx> |
31 | #include <StdPrs_WFRestrictedFace.hxx> |
32 | #include <StdPrs_ToolRFace.hxx> |
33 | #include <StdPrs_Curve.hxx> |
34 | #include <Prs3d_NListOfSequenceOfPnt.hxx> |
35 | |
36 | //========================================================================= |
37 | // function: Add |
38 | // purpose |
39 | //========================================================================= |
40 | |
41 | void StdPrs_WFRestrictedFace::Add |
42 | (const Handle (Prs3d_Presentation)& thePresentation, |
43 | const Handle(BRepAdaptor_HSurface)& theFace, |
44 | const Standard_Boolean theDrawUIso, |
45 | const Standard_Boolean theDrawVIso, |
46 | const Quantity_Length theDeflection, |
47 | const Standard_Integer theNbUIso, |
48 | const Standard_Integer theNBVIso, |
49 | const Handle(Prs3d_Drawer)& theDrawer, |
50 | Prs3d_NListOfSequenceOfPnt& theCurves) |
51 | { |
d7223c76 |
52 | Standard_Integer aNbPoints = theDrawer->Discretisation(); |
53 | StdPrs_ToolRFace aToolRst (theFace); |
54 | |
55 | // Compute bounds of the restriction |
56 | Standard_Real aUMin,aUMax,aVMin,aVMax; |
57 | Standard_Integer anI; |
58 | gp_Pnt2d aPoint1,aPoint2; |
59 | Bnd_Box2d aBndBox; |
60 | |
61 | for (aToolRst.Init(); aToolRst.More(); aToolRst.Next()) |
62 | { |
63 | Adaptor2d_Curve2dPtr aRCurve = aToolRst.Value(); |
64 | BndLib_Add2dCurve::Add(*aRCurve, Precision::PConfusion(), aBndBox); |
65 | } |
66 | if (!aBndBox.IsVoid()) |
67 | aBndBox.Get(aUMin, aVMin, aUMax, aVMax); |
68 | else |
69 | { // No pcurves -- take natural bounds |
70 | aUMin = theFace->Surface().FirstUParameter(); |
71 | aVMin = theFace->Surface().FirstVParameter(); |
72 | aUMax = theFace->Surface().LastUParameter(); |
73 | aVMax = theFace->Surface().LastVParameter(); |
74 | } |
75 | |
76 | // Load the isos |
77 | Hatch_Hatcher anIsoBuild(1.e-5,aToolRst.IsOriented()); |
78 | Standard_Boolean isFaceUClosed = theFace->IsUClosed(); |
79 | Standard_Boolean isFaceVClosed = theFace->IsVClosed(); |
80 | |
81 | if (!isFaceUClosed) |
82 | { |
83 | aUMin = aUMin + ( aUMax - aUMin) /1000.; |
84 | aUMax = aUMax - ( aUMax - aUMin) /1000.; |
85 | } |
86 | |
87 | if (!isFaceVClosed) |
88 | { |
89 | aVMin = aVMin + ( aVMax - aVMin) /1000.; |
90 | aVMax = aVMax - ( aVMax - aVMin) /1000.; |
91 | } |
92 | |
93 | if (theDrawUIso) |
94 | { |
95 | if (theNbUIso > 0) |
96 | { |
97 | isFaceUClosed = Standard_False; |
98 | Standard_Real du= isFaceUClosed ? (aUMax-aUMin)/theNbUIso : (aUMax-aUMin)/(1+theNbUIso); |
99 | for (anI=1; anI<=theNbUIso;anI++) |
100 | { |
101 | anIsoBuild.AddXLine(aUMin+du*anI); |
102 | } |
103 | } |
104 | } |
105 | if (theDrawVIso) |
106 | { |
107 | if (theNBVIso > 0) |
108 | { |
109 | isFaceVClosed = Standard_False; |
110 | Standard_Real dv= isFaceVClosed ?(aVMax-aVMin)/theNBVIso : (aVMax-aVMin)/(1+theNBVIso); |
111 | for (anI=1; anI<=theNBVIso;anI++) |
112 | { |
113 | anIsoBuild.AddYLine(aVMin+dv*anI); |
114 | } |
115 | } |
116 | } |
117 | |
118 | // Trim the isos |
119 | Standard_Real anU1, anU2, anU, aDU; |
120 | |
121 | for (aToolRst.Init(); aToolRst.More(); aToolRst.Next()) |
122 | { |
123 | TopAbs_Orientation anOrientation = aToolRst.Orientation(); |
124 | if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) |
125 | { |
126 | Adaptor2d_Curve2dPtr aRCurve = aToolRst.Value(); |
127 | anU1 = aRCurve->FirstParameter(); |
128 | anU2 = aRCurve->LastParameter(); |
129 | if (aRCurve->GetType() != GeomAbs_Line) |
130 | { |
131 | aDU = (anU2-anU1)/(aNbPoints-1); |
132 | aPoint2 = aRCurve->Value(anU1); |
133 | for (anI = 2; anI <= aNbPoints; ++anI) |
134 | { |
135 | anU = anU1 + (anI-1)*aDU; |
136 | aPoint1 = aPoint2; |
137 | aPoint2 = aRCurve->Value(anU); |
138 | if(anOrientation == TopAbs_FORWARD ) |
139 | anIsoBuild.Trim(aPoint1,aPoint2); |
140 | else |
141 | anIsoBuild.Trim(aPoint2,aPoint1); |
142 | } |
143 | } |
144 | else { |
145 | aPoint1 = aRCurve->Value(anU1); |
146 | aPoint2 = aRCurve->Value(anU2); |
147 | if(anOrientation == TopAbs_FORWARD ) |
148 | anIsoBuild.Trim(aPoint1,aPoint2); |
149 | else |
150 | anIsoBuild.Trim(aPoint2,aPoint1); |
151 | } |
152 | } |
153 | } |
154 | |
155 | // Draw the isos |
156 | Adaptor3d_IsoCurve anIsoCurve; |
157 | anIsoCurve.Load(theFace); |
158 | Handle(Geom_Curve) aBCurve; |
159 | const BRepAdaptor_Surface& aBSurface = *(BRepAdaptor_Surface*)&(theFace->Surface()); |
160 | GeomAbs_SurfaceType aFaceType = theFace->GetType(); |
161 | |
162 | Standard_Integer aNbLines = anIsoBuild.NbLines(); |
163 | Handle(Geom_Surface) aGeomBSurface; |
164 | if (aFaceType == GeomAbs_BezierSurface) |
165 | { |
166 | aGeomBSurface = aBSurface.Bezier(); |
167 | } |
168 | else if (aFaceType == GeomAbs_BSplineSurface) |
169 | { |
170 | aGeomBSurface = aBSurface.BSpline(); |
171 | } |
172 | |
173 | for (anI = 1; anI <= aNbLines; ++anI) |
174 | { |
175 | Standard_Integer NumberOfIntervals = anIsoBuild.NbIntervals(anI); |
176 | Standard_Real anIsoCoord = anIsoBuild.Coordinate(anI); |
177 | for (Standard_Integer aJ = 1; aJ <= NumberOfIntervals; aJ++) |
178 | { |
179 | Standard_Real b1=anIsoBuild.Start(anI,aJ),b2=anIsoBuild.End(anI,aJ); |
180 | |
181 | if(b1 == RealFirst() || b2 == RealLast()) |
182 | continue; |
183 | |
184 | TColgp_SequenceOfPnt aPoints; |
185 | if (!aGeomBSurface.IsNull()) |
186 | { |
187 | if (anIsoBuild.IsXLine(anI)) |
188 | aBCurve = aGeomBSurface->UIso(anIsoCoord); |
189 | else |
190 | aBCurve = aGeomBSurface->VIso(anIsoCoord); |
191 | |
192 | //Note that the isos are the part of the shape, it will be displayed after a computation the whole shape |
193 | //NbPoints = 30 - default parameter for computation of such curves |
194 | StdPrs_Curve::Add(thePresentation,GeomAdaptor_Curve(aBCurve), b1, b2, theDeflection, aPoints, 30, Standard_False); |
195 | theCurves.Append(aPoints); |
196 | } |
197 | else |
198 | { |
199 | if (anIsoBuild.IsXLine(anI)) |
200 | anIsoCurve.Load(GeomAbs_IsoU,anIsoCoord,b1,b2); |
201 | else |
202 | anIsoCurve.Load(GeomAbs_IsoV,anIsoCoord,b1,b2); |
203 | StdPrs_Curve::Add(thePresentation,anIsoCurve, theDeflection, theDrawer, aPoints, Standard_False); |
204 | theCurves.Append(aPoints); |
205 | } |
206 | } |
207 | } |
208 | } |
209 | |
210 | |
211 | //========================================================================= |
212 | // function: Match |
213 | // purpose |
214 | //========================================================================= |
215 | |
216 | Standard_Boolean StdPrs_WFRestrictedFace::Match |
217 | (const Quantity_Length theX, |
218 | const Quantity_Length theY, |
219 | const Quantity_Length theZ, |
220 | const Quantity_Length theDistance, |
221 | const Handle(BRepAdaptor_HSurface)& theFace, |
222 | const Standard_Boolean theDrawUIso, |
223 | const Standard_Boolean theDrawVIso, |
224 | const Quantity_Length theDeflection, |
225 | const Standard_Integer theNbUIso, |
226 | const Standard_Integer theNBVIso, |
227 | const Handle(Prs3d_Drawer)& theDrawer) |
228 | { |
229 | Standard_Real aLimit = theDrawer->MaximalParameterValue(); |
230 | Standard_Integer aNbPoints = theDrawer->Discretisation(); |
231 | StdPrs_ToolRFace aToolRst (theFace); |
232 | |
233 | // Compute bounds of the restriction |
234 | Standard_Real anUMin,anUMax,aVMin,aVMax; |
235 | Standard_Real anU,aV,aStep; |
236 | Standard_Integer anI,anNbP = 10; |
237 | anUMin = aVMin = RealLast(); |
238 | anUMax = aVMax = RealFirst(); |
239 | gp_Pnt2d aPoint1,aPoint2; |
240 | |
241 | for (aToolRst.Init(); aToolRst.More(); aToolRst.Next()) |
242 | { |
243 | Adaptor2d_Curve2dPtr aRCurve = aToolRst.Value(); |
244 | anU = aRCurve->FirstParameter(); |
245 | aV = aRCurve->LastParameter(); |
246 | if (aRCurve->GetType() != GeomAbs_Line) |
247 | { |
248 | aStep = ( aV - anU) / anNbP; |
249 | for (anI = 0; anI <= anNbP; ++anI) |
250 | { |
251 | gp_Pnt2d aRCurvePoint = aRCurve->Value(anU); |
252 | if (aRCurvePoint.X() < anUMin) anUMin = aRCurvePoint.X(); |
253 | if (aRCurvePoint.X() > anUMax) anUMax = aRCurvePoint.X(); |
254 | if (aRCurvePoint.Y() < aVMin) aVMin = aRCurvePoint.Y(); |
255 | if (aRCurvePoint.Y() > aVMax) aVMax = aRCurvePoint.Y(); |
256 | anU += aStep; |
257 | } |
258 | } |
259 | else |
260 | { |
261 | aPoint1 = aRCurve->Value(anU); |
262 | if (aPoint1.X() < anUMin) anUMin = aPoint1.X(); |
263 | if (aPoint1.X() > anUMax) anUMax = aPoint1.X(); |
264 | if (aPoint1.Y() < aVMin) aVMin = aPoint1.Y(); |
265 | if (aPoint1.Y() > aVMax) aVMax = aPoint1.Y(); |
266 | |
267 | aPoint2 = aRCurve->Value(aV); |
268 | if (aPoint2.X() < anUMin) anUMin = aPoint2.X(); |
269 | if (aPoint2.X() > anUMax) anUMax = aPoint2.X(); |
270 | if (aPoint2.Y() < aVMin) aVMin = aPoint2.Y(); |
271 | if (aPoint2.Y() > aVMax) aVMax = aPoint2.Y(); |
272 | } |
273 | } |
274 | |
275 | // Load the isos |
276 | Hatch_Hatcher anIsoBuild(1.e-5,aToolRst.IsOriented()); |
277 | Standard_Boolean anUClosed = theFace->IsUClosed(); |
278 | Standard_Boolean aVClosed = theFace->IsVClosed(); |
279 | |
280 | if ( ! anUClosed ) |
281 | { |
282 | anUMin = anUMin + ( anUMax - anUMin) /1000.; |
283 | anUMax = anUMax - ( anUMax - anUMin) /1000.; |
284 | } |
285 | |
286 | if ( ! aVClosed ) |
287 | { |
288 | aVMin = aVMin + ( aVMax - aVMin) /1000.; |
289 | aVMax = aVMax - ( aVMax - aVMin) /1000.; |
290 | } |
291 | |
292 | if (theDrawUIso) |
293 | { |
294 | if (theNbUIso > 0) |
295 | { |
296 | anUClosed = Standard_False; |
297 | Standard_Real du= anUClosed ? (anUMax-anUMin)/theNbUIso : (anUMax-anUMin)/(1+theNbUIso); |
298 | for (anI=1; anI<=theNbUIso;anI++){ |
299 | anIsoBuild.AddXLine(anUMin+du*anI); |
300 | } |
301 | } |
302 | } |
303 | if (theDrawVIso){ |
304 | if ( theNBVIso > 0) { |
305 | aVClosed = Standard_False; |
306 | Standard_Real dv= aVClosed ?(aVMax-aVMin)/theNBVIso : (aVMax-aVMin)/(1+theNBVIso); |
307 | for (anI=1; anI<=theNBVIso;anI++){ |
308 | anIsoBuild.AddYLine(aVMin+dv*anI); |
309 | } |
310 | } |
311 | } |
312 | |
313 | // Trim the isos |
314 | Standard_Real anU1, anU2, aDU; |
315 | |
316 | for (aToolRst.Init(); aToolRst.More(); aToolRst.Next()) |
317 | { |
318 | TopAbs_Orientation Orient = aToolRst.Orientation(); |
319 | if (Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED) |
320 | { |
321 | Adaptor2d_Curve2dPtr aRCurve = aToolRst.Value(); |
322 | anU1 = aRCurve->FirstParameter(); |
323 | anU2 = aRCurve->LastParameter(); |
324 | if (aRCurve->GetType() != GeomAbs_Line) { |
325 | aDU = (anU2-anU1)/(aNbPoints-1); |
326 | aPoint2 = aRCurve->Value(anU1); |
327 | for (anI = 2; anI <= aNbPoints; anI++) { |
328 | anU = anU1 + (anI-1)*aDU; |
329 | aPoint1 = aPoint2; |
330 | aPoint2 = aRCurve->Value(anU); |
331 | if(Orient == TopAbs_FORWARD ) |
332 | anIsoBuild.Trim(aPoint1,aPoint2); |
333 | else |
334 | anIsoBuild.Trim(aPoint2,aPoint1); |
335 | } |
336 | } |
337 | else { |
338 | aPoint1 = aRCurve->Value(anU1); |
339 | aPoint2 = aRCurve->Value(anU2); |
340 | if(Orient == TopAbs_FORWARD ) |
341 | anIsoBuild.Trim(aPoint1,aPoint2); |
342 | else |
343 | anIsoBuild.Trim(aPoint2,aPoint1); |
344 | } |
345 | } |
346 | } |
347 | |
348 | // Draw the isos |
349 | |
350 | Adaptor3d_IsoCurve anIso; |
351 | anIso.Load(theFace); |
352 | Standard_Integer aNbLines = anIsoBuild.NbLines(); |
353 | |
354 | for (anI = 1; anI <= aNbLines; anI++) |
355 | { |
356 | Standard_Integer aNbIntervals = anIsoBuild.NbIntervals(anI); |
357 | Standard_Real aCoord = anIsoBuild.Coordinate(anI); |
358 | for (Standard_Integer j = 1; j <= aNbIntervals; j++) |
359 | { |
360 | Standard_Real anIsoStart=anIsoBuild.Start(anI,j),anIsoEnd=anIsoBuild.End(anI,j); |
361 | |
362 | anIsoStart = anIsoStart == RealFirst() ? - aLimit : anIsoStart; |
363 | anIsoEnd = anIsoEnd == RealLast() ? aLimit : anIsoEnd; |
364 | |
365 | |
366 | if (anIsoBuild.IsXLine(anI)) |
367 | anIso.Load(GeomAbs_IsoU,aCoord,anIsoStart,anIsoEnd); |
368 | else |
369 | anIso.Load(GeomAbs_IsoV,aCoord,anIsoStart,anIsoEnd); |
370 | |
371 | if (StdPrs_Curve::Match(theX,theY,theZ,theDistance,anIso, |
372 | theDeflection, aLimit, aNbPoints)) |
373 | return Standard_True; |
374 | |
375 | |
376 | } |
377 | } |
378 | return Standard_False; |
379 | } |
380 | |
381 | |
382 | //========================================================================= |
383 | // function: Add |
384 | // purpose |
385 | //========================================================================= |
386 | |
387 | void StdPrs_WFRestrictedFace::Add |
388 | (const Handle (Prs3d_Presentation)& thePresentation, |
389 | const Handle(BRepAdaptor_HSurface)& theFace, |
390 | const Handle (Prs3d_Drawer)& theDrawer) |
391 | { |
392 | Prs3d_NListOfSequenceOfPnt aCurves; |
393 | StdPrs_WFRestrictedFace::Add (thePresentation, |
394 | theFace, |
395 | Standard_True, |
396 | Standard_True, |
397 | theDrawer->MaximalChordialDeviation(), |
398 | theDrawer->UIsoAspect()->Number(), |
399 | theDrawer->VIsoAspect()->Number(), |
400 | theDrawer, |
401 | aCurves); |
402 | } |
403 | |
404 | |
405 | //========================================================================= |
406 | // function: AddUIso |
407 | // purpose |
408 | //========================================================================= |
409 | |
410 | void StdPrs_WFRestrictedFace::AddUIso |
411 | (const Handle (Prs3d_Presentation)& thePresentation, |
412 | const Handle(BRepAdaptor_HSurface)& theFace, |
413 | const Handle (Prs3d_Drawer)& theDrawer) |
414 | { |
415 | Prs3d_NListOfSequenceOfPnt aCurves; |
416 | StdPrs_WFRestrictedFace::Add (thePresentation, |
417 | theFace, |
418 | Standard_True, |
419 | Standard_False, |
420 | theDrawer->MaximalChordialDeviation(), |
421 | theDrawer->UIsoAspect()->Number(), |
422 | theDrawer->VIsoAspect()->Number(), |
423 | theDrawer, |
424 | aCurves); |
425 | } |
426 | |
427 | |
428 | //========================================================================= |
429 | // function: AddVIso |
430 | // purpose |
431 | //========================================================================= |
432 | |
433 | void StdPrs_WFRestrictedFace::AddVIso |
434 | (const Handle (Prs3d_Presentation)& thePresentation, |
435 | const Handle(BRepAdaptor_HSurface)& theFace, |
436 | const Handle (Prs3d_Drawer)& theDrawer) |
437 | { |
438 | Prs3d_NListOfSequenceOfPnt aCurves; |
439 | StdPrs_WFRestrictedFace::Add (thePresentation, |
440 | theFace, |
441 | Standard_False, |
442 | Standard_True, |
443 | theDrawer->MaximalChordialDeviation(), |
444 | theDrawer->UIsoAspect()->Number(), |
445 | theDrawer->VIsoAspect()->Number(), |
446 | theDrawer, |
447 | aCurves); |
448 | } |
449 | |
450 | |
451 | //========================================================================= |
452 | // function: Match |
453 | // purpose |
454 | //========================================================================= |
455 | |
456 | Standard_Boolean StdPrs_WFRestrictedFace::Match |
457 | (const Quantity_Length theX, |
458 | const Quantity_Length theY, |
459 | const Quantity_Length theZ, |
460 | const Quantity_Length theDistance, |
461 | const Handle(BRepAdaptor_HSurface)& theFace, |
462 | const Handle (Prs3d_Drawer)& theDrawer) |
463 | { |
464 | return StdPrs_WFRestrictedFace::Match ( |
465 | theX, theY, theZ, theDistance, |
466 | theFace, |
467 | Standard_True, |
468 | Standard_True, |
469 | theDrawer->MaximalChordialDeviation(), |
470 | theDrawer->UIsoAspect()->Number(), |
471 | theDrawer->VIsoAspect()->Number(), |
472 | theDrawer); |
473 | } |
474 | |
475 | |
476 | //========================================================================= |
477 | // function: MatchUIso |
478 | // purpose |
479 | //========================================================================= |
480 | |
481 | Standard_Boolean StdPrs_WFRestrictedFace::MatchUIso |
482 | (const Quantity_Length theX, |
483 | const Quantity_Length theY, |
484 | const Quantity_Length theZ, |
485 | const Quantity_Length theDistance, |
486 | const Handle(BRepAdaptor_HSurface)& theFace, |
487 | const Handle (Prs3d_Drawer)& theDrawer) |
488 | { |
489 | return StdPrs_WFRestrictedFace::Match ( |
490 | theX, theY, theZ,theDistance, |
491 | theFace, |
492 | Standard_True, |
493 | Standard_False, |
494 | theDrawer->MaximalChordialDeviation(), |
495 | theDrawer->UIsoAspect()->Number(), |
496 | theDrawer->VIsoAspect()->Number(), |
497 | theDrawer); |
498 | } |
499 | |
500 | |
501 | //========================================================================= |
502 | // function: MatchVIso |
503 | // purpose |
504 | //========================================================================= |
505 | |
506 | Standard_Boolean StdPrs_WFRestrictedFace::MatchVIso |
507 | (const Quantity_Length theX, |
508 | const Quantity_Length theY, |
509 | const Quantity_Length theZ, |
510 | const Quantity_Length theDistance, |
511 | const Handle(BRepAdaptor_HSurface)& theFace, |
512 | const Handle (Prs3d_Drawer)& theDrawer) |
513 | { |
514 | return StdPrs_WFRestrictedFace::Match ( |
515 | theX, theY, theZ, theDistance, |
516 | theFace, |
517 | Standard_False, |
518 | Standard_True, |
519 | theDrawer->MaximalChordialDeviation(), |
520 | theDrawer->UIsoAspect()->Number(), |
521 | theDrawer->VIsoAspect()->Number(), |
522 | theDrawer); |
523 | } |