1 // Copyright (c) 2013-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Hatch_Hatcher.hxx>
15 #include <Graphic3d_Group.hxx>
16 #include <gp_Pnt.hxx>
17 #include <Prs3d_IsoAspect.hxx>
18 #include <Adaptor3d_IsoCurve.hxx>
19 #include <Bnd_Box2d.hxx>
20 #include <BndLib_Add2dCurve.hxx>
21 #include <Precision.hxx>
22 #include <GeomAdaptor_Curve.hxx>
23 #include <Geom_BezierSurface.hxx>
24 #include <Geom_BSplineSurface.hxx>
25 #include <GeomAbs_SurfaceType.hxx>
26 #include <Geom_Surface.hxx>
27 #include <StdPrs_WFRestrictedFace.hxx>
28 #include <StdPrs_ToolRFace.hxx>
29 #include <StdPrs_Curve.hxx>
30 #include <Prs3d_NListOfSequenceOfPnt.hxx>
31
32 //=========================================================================
33 // function: Add
34 // purpose
35 //=========================================================================
36
Add(const Handle (Prs3d_Presentation)& thePresentation,const Handle (BRepAdaptor_Surface)& theFace,const Standard_Boolean theDrawUIso,const Standard_Boolean theDrawVIso,const Standard_Integer theNbUIso,const Standard_Integer theNBVIso,const Handle (Prs3d_Drawer)& theDrawer,Prs3d_NListOfSequenceOfPnt & theCurves)37 void StdPrs_WFRestrictedFace::Add
38 (const Handle (Prs3d_Presentation)& thePresentation,
39 const Handle(BRepAdaptor_Surface)& theFace,
40 const Standard_Boolean theDrawUIso,
41 const Standard_Boolean theDrawVIso,
42 const Standard_Integer theNbUIso,
43 const Standard_Integer theNBVIso,
44 const Handle(Prs3d_Drawer)& theDrawer,
45 Prs3d_NListOfSequenceOfPnt& theCurves)
46 {
47 Standard_Integer aNbPoints = theDrawer->Discretisation();
48 StdPrs_ToolRFace aToolRst (theFace);
49
50 // Compute bounds of the restriction
51 Standard_Real aUMin,aUMax,aVMin,aVMax;
52 Standard_Integer anI;
53 gp_Pnt2d aPoint1,aPoint2;
54 Bnd_Box2d aBndBox;
55
56 for (aToolRst.Init(); aToolRst.More(); aToolRst.Next())
57 {
58 const Adaptor2d_Curve2d& aRCurve = aToolRst.Value();
59 BndLib_Add2dCurve::Add(aRCurve, Precision::PConfusion(), aBndBox);
60 }
61 if (!aBndBox.IsVoid())
62 aBndBox.Get(aUMin, aVMin, aUMax, aVMax);
63 else
64 { // No pcurves -- take natural bounds
65 aUMin = theFace->Surface().FirstUParameter();
66 aVMin = theFace->Surface().FirstVParameter();
67 aUMax = theFace->Surface().LastUParameter();
68 aVMax = theFace->Surface().LastVParameter();
69 }
70
71 // Load the isos
72 Hatch_Hatcher anIsoBuild(1.e-5,aToolRst.IsOriented());
73 Standard_Boolean isFaceUClosed = theFace->IsUClosed();
74 Standard_Boolean isFaceVClosed = theFace->IsVClosed();
75
76 if (!isFaceUClosed)
77 {
78 aUMin = aUMin + ( aUMax - aUMin) /1000.;
79 aUMax = aUMax - ( aUMax - aUMin) /1000.;
80 }
81
82 if (!isFaceVClosed)
83 {
84 aVMin = aVMin + ( aVMax - aVMin) /1000.;
85 aVMax = aVMax - ( aVMax - aVMin) /1000.;
86 }
87
88 if (theDrawUIso)
89 {
90 if (theNbUIso > 0)
91 {
92 isFaceUClosed = Standard_False;
93 Standard_Real du= isFaceUClosed ? (aUMax-aUMin)/theNbUIso : (aUMax-aUMin)/(1+theNbUIso);
94 for (anI=1; anI<=theNbUIso;anI++)
95 {
96 anIsoBuild.AddXLine(aUMin+du*anI);
97 }
98 }
99 }
100 if (theDrawVIso)
101 {
102 if (theNBVIso > 0)
103 {
104 isFaceVClosed = Standard_False;
105 Standard_Real dv= isFaceVClosed ?(aVMax-aVMin)/theNBVIso : (aVMax-aVMin)/(1+theNBVIso);
106 for (anI=1; anI<=theNBVIso;anI++)
107 {
108 anIsoBuild.AddYLine(aVMin+dv*anI);
109 }
110 }
111 }
112
113 // Trim the isos
114 Standard_Real anU1, anU2, anU, aDU;
115
116 for (aToolRst.Init(); aToolRst.More(); aToolRst.Next())
117 {
118 TopAbs_Orientation anOrientation = aToolRst.Orientation();
119 const Adaptor2d_Curve2d* aRCurve = &aToolRst.Value();
120 anU1 = aRCurve->FirstParameter();
121 anU2 = aRCurve->LastParameter();
122 if (aRCurve->GetType() != GeomAbs_Line)
123 {
124 aDU = (anU2-anU1)/(aNbPoints-1);
125 aPoint2 = aRCurve->Value(anU1);
126 for (anI = 2; anI <= aNbPoints; ++anI)
127 {
128 anU = anU1 + (anI-1)*aDU;
129 aPoint1 = aPoint2;
130 aPoint2 = aRCurve->Value(anU);
131 if(anOrientation == TopAbs_FORWARD )
132 anIsoBuild.Trim(aPoint1,aPoint2);
133 else
134 anIsoBuild.Trim(aPoint2,aPoint1);
135 }
136 }
137 else {
138 aPoint1 = aRCurve->Value(anU1);
139 aPoint2 = aRCurve->Value(anU2);
140 if(anOrientation == TopAbs_FORWARD )
141 anIsoBuild.Trim(aPoint1,aPoint2);
142 else
143 anIsoBuild.Trim(aPoint2,aPoint1);
144 }
145 }
146
147 // Draw the isos
148 Adaptor3d_IsoCurve anIsoCurve;
149 anIsoCurve.Load(theFace);
150 Handle(Geom_Curve) aBCurve;
151 const BRepAdaptor_Surface& aBSurface = *theFace;
152 GeomAbs_SurfaceType aFaceType = theFace->GetType();
153
154 Standard_Integer aNbLines = anIsoBuild.NbLines();
155 Handle(Geom_Surface) aGeomBSurface;
156 if (aFaceType == GeomAbs_BezierSurface)
157 {
158 aGeomBSurface = aBSurface.Bezier();
159 }
160 else if (aFaceType == GeomAbs_BSplineSurface)
161 {
162 aGeomBSurface = aBSurface.BSpline();
163 }
164
165 for (anI = 1; anI <= aNbLines; ++anI)
166 {
167 Standard_Integer NumberOfIntervals = anIsoBuild.NbIntervals(anI);
168 Standard_Real anIsoCoord = anIsoBuild.Coordinate(anI);
169 for (Standard_Integer aJ = 1; aJ <= NumberOfIntervals; aJ++)
170 {
171 Standard_Real b1=anIsoBuild.Start(anI,aJ),b2=anIsoBuild.End(anI,aJ);
172
173 if(b1 == RealFirst() || b2 == RealLast())
174 continue;
175
176 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt;
177 if (!aGeomBSurface.IsNull())
178 {
179 if (anIsoBuild.IsXLine (anI))
180 {
181 aBCurve = aGeomBSurface->UIso (anIsoCoord);
182 }
183 else
184 {
185 aBCurve = aGeomBSurface->VIso (anIsoCoord);
186 }
187
188 //Note that the isos are the part of the shape, it will be displayed after a computation the whole shape
189 //NbPoints = 30 - default parameter for computation of such curves
190 StdPrs_Curve::Add (thePresentation, GeomAdaptor_Curve (aBCurve), b1, b2, aPoints->ChangeSequence(), 30, Standard_False);
191 theCurves.Append (aPoints);
192 }
193 else
194 {
195 if (anIsoBuild.IsXLine (anI))
196 {
197 anIsoCurve.Load (GeomAbs_IsoU, anIsoCoord, b1, b2);
198 }
199 else
200 {
201 anIsoCurve.Load(GeomAbs_IsoV, anIsoCoord, b1, b2);
202 }
203 StdPrs_Curve::Add (thePresentation, anIsoCurve, theDrawer, aPoints->ChangeSequence(), Standard_False);
204 theCurves.Append (aPoints);
205 }
206 }
207 }
208 }
209
210
211 //=========================================================================
212 // function: Match
213 // purpose
214 //=========================================================================
215
Match(const Standard_Real theX,const Standard_Real theY,const Standard_Real theZ,const Standard_Real theDistance,const Handle (BRepAdaptor_Surface)& theFace,const Standard_Boolean theDrawUIso,const Standard_Boolean theDrawVIso,const Standard_Real theDeflection,const Standard_Integer theNbUIso,const Standard_Integer theNBVIso,const Handle (Prs3d_Drawer)& theDrawer)216 Standard_Boolean StdPrs_WFRestrictedFace::Match
217 (const Standard_Real theX,
218 const Standard_Real theY,
219 const Standard_Real theZ,
220 const Standard_Real theDistance,
221 const Handle(BRepAdaptor_Surface)& theFace,
222 const Standard_Boolean theDrawUIso,
223 const Standard_Boolean theDrawVIso,
224 const Standard_Real 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 const Adaptor2d_Curve2d* 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 const Adaptor2d_Curve2d* aRCurve = &aToolRst.Value();
320 anU1 = aRCurve->FirstParameter();
321 anU2 = aRCurve->LastParameter();
322 if (aRCurve->GetType() != GeomAbs_Line) {
323 aDU = (anU2-anU1)/(aNbPoints-1);
324 aPoint2 = aRCurve->Value(anU1);
325 for (anI = 2; anI <= aNbPoints; anI++) {
326 anU = anU1 + (anI-1)*aDU;
327 aPoint1 = aPoint2;
328 aPoint2 = aRCurve->Value(anU);
329 if(Orient == TopAbs_FORWARD )
330 anIsoBuild.Trim(aPoint1,aPoint2);
331 else
332 anIsoBuild.Trim(aPoint2,aPoint1);
333 }
334 }
335 else {
336 aPoint1 = aRCurve->Value(anU1);
337 aPoint2 = aRCurve->Value(anU2);
338 if(Orient == TopAbs_FORWARD )
339 anIsoBuild.Trim(aPoint1,aPoint2);
340 else
341 anIsoBuild.Trim(aPoint2,aPoint1);
342 }
343 }
344
345 // Draw the isos
346
347 Adaptor3d_IsoCurve anIso;
348 anIso.Load(theFace);
349 Standard_Integer aNbLines = anIsoBuild.NbLines();
350
351 for (anI = 1; anI <= aNbLines; anI++)
352 {
353 Standard_Integer aNbIntervals = anIsoBuild.NbIntervals(anI);
354 Standard_Real aCoord = anIsoBuild.Coordinate(anI);
355 for (Standard_Integer j = 1; j <= aNbIntervals; j++)
356 {
357 Standard_Real anIsoStart=anIsoBuild.Start(anI,j),anIsoEnd=anIsoBuild.End(anI,j);
358
359 anIsoStart = anIsoStart == RealFirst() ? - aLimit : anIsoStart;
360 anIsoEnd = anIsoEnd == RealLast() ? aLimit : anIsoEnd;
361
362
363 if (anIsoBuild.IsXLine(anI))
364 anIso.Load(GeomAbs_IsoU,aCoord,anIsoStart,anIsoEnd);
365 else
366 anIso.Load(GeomAbs_IsoV,aCoord,anIsoStart,anIsoEnd);
367
368 if (StdPrs_Curve::Match(theX,theY,theZ,theDistance,anIso,
369 theDeflection, aLimit, aNbPoints))
370 return Standard_True;
371
372
373 }
374 }
375 return Standard_False;
376 }
377
378
379 //=========================================================================
380 // function: Add
381 // purpose
382 //=========================================================================
383
Add(const Handle (Prs3d_Presentation)& thePresentation,const Handle (BRepAdaptor_Surface)& theFace,const Handle (Prs3d_Drawer)& theDrawer)384 void StdPrs_WFRestrictedFace::Add
385 (const Handle (Prs3d_Presentation)& thePresentation,
386 const Handle(BRepAdaptor_Surface)& theFace,
387 const Handle (Prs3d_Drawer)& theDrawer)
388 {
389 Prs3d_NListOfSequenceOfPnt aCurves;
390 StdPrs_WFRestrictedFace::Add (thePresentation,
391 theFace,
392 Standard_True,
393 Standard_True,
394 theDrawer->UIsoAspect()->Number(),
395 theDrawer->VIsoAspect()->Number(),
396 theDrawer,
397 aCurves);
398 }
399
400
401 //=========================================================================
402 // function: AddUIso
403 // purpose
404 //=========================================================================
405
AddUIso(const Handle (Prs3d_Presentation)& thePresentation,const Handle (BRepAdaptor_Surface)& theFace,const Handle (Prs3d_Drawer)& theDrawer)406 void StdPrs_WFRestrictedFace::AddUIso
407 (const Handle (Prs3d_Presentation)& thePresentation,
408 const Handle(BRepAdaptor_Surface)& theFace,
409 const Handle (Prs3d_Drawer)& theDrawer)
410 {
411 Prs3d_NListOfSequenceOfPnt aCurves;
412 StdPrs_WFRestrictedFace::Add (thePresentation,
413 theFace,
414 Standard_True,
415 Standard_False,
416 theDrawer->UIsoAspect()->Number(),
417 theDrawer->VIsoAspect()->Number(),
418 theDrawer,
419 aCurves);
420 }
421
422
423 //=========================================================================
424 // function: AddVIso
425 // purpose
426 //=========================================================================
427
AddVIso(const Handle (Prs3d_Presentation)& thePresentation,const Handle (BRepAdaptor_Surface)& theFace,const Handle (Prs3d_Drawer)& theDrawer)428 void StdPrs_WFRestrictedFace::AddVIso
429 (const Handle (Prs3d_Presentation)& thePresentation,
430 const Handle(BRepAdaptor_Surface)& theFace,
431 const Handle (Prs3d_Drawer)& theDrawer)
432 {
433 Prs3d_NListOfSequenceOfPnt aCurves;
434 StdPrs_WFRestrictedFace::Add (thePresentation,
435 theFace,
436 Standard_False,
437 Standard_True,
438 theDrawer->UIsoAspect()->Number(),
439 theDrawer->VIsoAspect()->Number(),
440 theDrawer,
441 aCurves);
442 }
443
444
445 //=========================================================================
446 // function: Match
447 // purpose
448 //=========================================================================
449
Match(const Standard_Real theX,const Standard_Real theY,const Standard_Real theZ,const Standard_Real theDistance,const Handle (BRepAdaptor_Surface)& theFace,const Handle (Prs3d_Drawer)& theDrawer)450 Standard_Boolean StdPrs_WFRestrictedFace::Match
451 (const Standard_Real theX,
452 const Standard_Real theY,
453 const Standard_Real theZ,
454 const Standard_Real theDistance,
455 const Handle(BRepAdaptor_Surface)& theFace,
456 const Handle (Prs3d_Drawer)& theDrawer)
457 {
458 return StdPrs_WFRestrictedFace::Match (
459 theX, theY, theZ, theDistance,
460 theFace,
461 Standard_True,
462 Standard_True,
463 theDrawer->MaximalChordialDeviation(),
464 theDrawer->UIsoAspect()->Number(),
465 theDrawer->VIsoAspect()->Number(),
466 theDrawer);
467 }
468
469
470 //=========================================================================
471 // function: MatchUIso
472 // purpose
473 //=========================================================================
474
MatchUIso(const Standard_Real theX,const Standard_Real theY,const Standard_Real theZ,const Standard_Real theDistance,const Handle (BRepAdaptor_Surface)& theFace,const Handle (Prs3d_Drawer)& theDrawer)475 Standard_Boolean StdPrs_WFRestrictedFace::MatchUIso
476 (const Standard_Real theX,
477 const Standard_Real theY,
478 const Standard_Real theZ,
479 const Standard_Real theDistance,
480 const Handle(BRepAdaptor_Surface)& theFace,
481 const Handle (Prs3d_Drawer)& theDrawer)
482 {
483 return StdPrs_WFRestrictedFace::Match (
484 theX, theY, theZ,theDistance,
485 theFace,
486 Standard_True,
487 Standard_False,
488 theDrawer->MaximalChordialDeviation(),
489 theDrawer->UIsoAspect()->Number(),
490 theDrawer->VIsoAspect()->Number(),
491 theDrawer);
492 }
493
494
495 //=========================================================================
496 // function: MatchVIso
497 // purpose
498 //=========================================================================
499
MatchVIso(const Standard_Real theX,const Standard_Real theY,const Standard_Real theZ,const Standard_Real theDistance,const Handle (BRepAdaptor_Surface)& theFace,const Handle (Prs3d_Drawer)& theDrawer)500 Standard_Boolean StdPrs_WFRestrictedFace::MatchVIso
501 (const Standard_Real theX,
502 const Standard_Real theY,
503 const Standard_Real theZ,
504 const Standard_Real theDistance,
505 const Handle(BRepAdaptor_Surface)& theFace,
506 const Handle (Prs3d_Drawer)& theDrawer)
507 {
508 return StdPrs_WFRestrictedFace::Match (
509 theX, theY, theZ, theDistance,
510 theFace,
511 Standard_False,
512 Standard_True,
513 theDrawer->MaximalChordialDeviation(),
514 theDrawer->UIsoAspect()->Number(),
515 theDrawer->VIsoAspect()->Number(),
516 theDrawer);
517 }
518