1 // Created on: 1995-08-04
2 // Created by: Modelistation
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 // Great zoom leads to non-coincidence of
23 // a point and non-infinite lines passing throught this point:
26 #include <StdPrs_Curve.ixx>
28 #include <Graphic3d_ArrayOfSegments.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_Group.hxx>
31 #include <Prs3d_LineAspect.hxx>
32 #include <Prs3d_Arrow.hxx>
33 #include <Prs3d_ArrowAspect.hxx>
35 #include <gp_Circ.hxx>
39 #include <Bnd_Box.hxx>
40 #include <Precision.hxx>
41 #include <TColgp_SequenceOfPnt.hxx>
44 //==================================================================
45 // function: FindLimits
47 //==================================================================
48 static void FindLimits(const Adaptor3d_Curve& aCurve,
49 const Standard_Real aLimit,
53 First = aCurve.FirstParameter();
54 Last = aCurve.LastParameter();
55 Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
56 Standard_Boolean lastInf = Precision::IsPositiveInfinite(Last);
58 if (firstInf || lastInf) {
60 Standard_Real delta = 1;
61 if (firstInf && lastInf) {
68 } while (P1.Distance(P2) < aLimit);
76 } while (P1.Distance(P2) < aLimit);
84 } while (P1.Distance(P2) < aLimit);
90 //==================================================================
91 // function: DrawCurve
93 //==================================================================
94 static void DrawCurve (const Adaptor3d_Curve& aCurve,
95 const Handle(Graphic3d_Group) aGroup,
96 const Standard_Integer NbP,
97 const Standard_Real U1,
98 const Standard_Real U2,
99 TColgp_SequenceOfPnt& Points,
100 const Standard_Boolean drawCurve)
102 Standard_Integer nbintervals = 1;
104 if (aCurve.GetType() == GeomAbs_BSplineCurve) {
105 nbintervals = aCurve.NbKnots() - 1;
106 nbintervals = Max(1, nbintervals/3);
109 switch (aCurve.GetType())
113 gp_Pnt p1 = aCurve.Value(U1);
114 gp_Pnt p2 = aCurve.Value(U2);
119 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
120 aPrims->AddVertex(p1);
121 aPrims->AddVertex(p2);
122 aGroup->AddPrimitiveArray(aPrims);
128 const Standard_Integer N = Max(2, NbP*nbintervals);
129 const Standard_Real DU = (U2-U1) / (N-1);
132 Handle(Graphic3d_ArrayOfPolylines) aPrims;
134 aPrims = new Graphic3d_ArrayOfPolylines(N);
136 for (Standard_Integer i = 1; i <= N;i++) {
137 p = aCurve.Value(U1 + (i-1)*DU);
140 aPrims->AddVertex(p);
143 aGroup->AddPrimitiveArray(aPrims);
149 //==================================================================
150 // function: MatchCurve
152 //==================================================================
153 static Standard_Boolean MatchCurve (
154 const Quantity_Length X,
155 const Quantity_Length Y,
156 const Quantity_Length Z,
157 const Quantity_Length aDistance,
158 const Adaptor3d_Curve& aCurve,
159 const Quantity_Length TheDeflection,
160 const Standard_Integer NbP,
161 const Standard_Real U1,
162 const Standard_Real U2)
164 Quantity_Length retdist;
165 switch (aCurve.GetType())
169 gp_Pnt p1 = aCurve.Value(U1);
170 if ( Abs(X-p1.X()) + Abs(Y-p1.Y()) + Abs(Z-p1.Z()) <= aDistance)
171 return Standard_True;
172 gp_Pnt p2 = aCurve.Value(U2);
173 if ( Abs(X-p2.X()) + Abs(Y-p2.Y()) + Abs(Z-p2.Z()) <= aDistance)
174 return Standard_True;
175 return Prs3d::MatchSegment(X,Y,Z,aDistance,p1,p2,retdist);
179 const Standard_Real Radius = aCurve.Circle().Radius();
180 const Standard_Real DU = Sqrt(8.0 * TheDeflection / Radius);
181 const Standard_Real Er = Abs( U2 - U1) / DU;
182 const Standard_Integer N = Max(2, (Standard_Integer)IntegerPart(Er));
185 for (Standard_Integer Index = 1; Index <= N+1; Index++) {
186 p2 = aCurve.Value(U1 + (Index - 1) * DU);
187 if ( Abs(X-p2.X()) + Abs(Y-p2.Y()) + Abs(Z-p2.Z()) <= aDistance)
188 return Standard_True;
191 if (Prs3d::MatchSegment(X,Y,Z,aDistance,p1,p2,retdist))
192 return Standard_True;
201 const Standard_Real DU = (U2-U1) / (NbP-1);
203 for (Standard_Integer i=1;i<=NbP;i++) {
204 p2 = aCurve.Value(U1 + (i-1)*DU);
205 if ( Abs(X-p2.X()) + Abs(Y-p2.Y()) + Abs(Z-p2.Z()) <= aDistance)
206 return Standard_True;
208 if (Prs3d::MatchSegment(X,Y,Z,aDistance,p1,p2,retdist))
209 return Standard_True;
215 return Standard_False;
219 //==================================================================
222 //==================================================================
223 void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation,
224 const Adaptor3d_Curve& aCurve,
225 const Handle (Prs3d_Drawer)& aDrawer,
226 const Standard_Boolean drawCurve)
228 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(aDrawer->LineAspect()->Aspect());
230 Standard_Real V1, V2;
231 FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2);
233 const Standard_Integer NbPoints = aDrawer->Discretisation();
234 TColgp_SequenceOfPnt Pnts;
235 DrawCurve(aCurve,Prs3d_Root::CurrentGroup(aPresentation),NbPoints,V1,V2,Pnts,drawCurve);
237 if (aDrawer->LineArrowDraw()) {
240 aCurve.D1(aCurve.LastParameter(),Location,Direction);
241 Prs3d_Arrow::Draw (aPresentation,Location,gp_Dir(Direction),
242 aDrawer->ArrowAspect()->Angle(),
243 aDrawer->ArrowAspect()->Length());
248 //==================================================================
251 //==================================================================
252 void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation,
253 const Adaptor3d_Curve& aCurve,
254 const Quantity_Length aDeflection,
255 const Handle(Prs3d_Drawer)& aDrawer,
256 TColgp_SequenceOfPnt& Points,
257 const Standard_Boolean drawCurve)
259 Standard_Real V1, V2;
260 FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2);
262 const Standard_Integer NbPoints = aDrawer->Discretisation();
263 DrawCurve(aCurve,Prs3d_Root::CurrentGroup(aPresentation),NbPoints,V1,V2,Points,drawCurve);
267 //==================================================================
270 //==================================================================
271 void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation,
272 const Adaptor3d_Curve& aCurve,
273 const Standard_Real U1,
274 const Standard_Real U2,
275 const Quantity_Length aDeflection,
276 TColgp_SequenceOfPnt& Points,
277 const Standard_Integer NbPoints,
278 const Standard_Boolean drawCurve)
280 DrawCurve(aCurve,Prs3d_Root::CurrentGroup(aPresentation),NbPoints,U1,U2,Points,drawCurve);
284 //==================================================================
287 //==================================================================
288 void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation,
289 const Adaptor3d_Curve& aCurve,
290 const Standard_Real U1,
291 const Standard_Real U2,
292 const Handle (Prs3d_Drawer)& aDrawer,
293 const Standard_Boolean drawCurve)
295 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(aDrawer->LineAspect()->Aspect());
297 Standard_Real V1 = U1;
298 Standard_Real V2 = U2;
300 if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
301 if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
303 const Standard_Integer NbPoints = aDrawer->Discretisation();
304 TColgp_SequenceOfPnt Pnts;
305 DrawCurve(aCurve,Prs3d_Root::CurrentGroup(aPresentation),NbPoints,V1,V2,Pnts,drawCurve);
307 if (aDrawer->LineArrowDraw()) {
310 aCurve.D1(aCurve.LastParameter(),Location,Direction);
311 Prs3d_Arrow::Draw (aPresentation,Location,gp_Dir(Direction),
312 aDrawer->ArrowAspect()->Angle(),
313 aDrawer->ArrowAspect()->Length());
318 //==================================================================
321 //==================================================================
322 Standard_Boolean StdPrs_Curve::Match
323 (const Quantity_Length X,
324 const Quantity_Length Y,
325 const Quantity_Length Z,
326 const Quantity_Length aDistance,
327 const Adaptor3d_Curve& aCurve,
328 const Handle (Prs3d_Drawer)& aDrawer)
330 Standard_Real V1, V2;
331 FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2);
333 const Standard_Integer NbPoints = aDrawer->Discretisation();
334 return MatchCurve(X,Y,Z,aDistance,aCurve,
335 aDrawer->MaximalChordialDeviation(),NbPoints,V1,V2);
340 //==================================================================
343 //==================================================================
344 Standard_Boolean StdPrs_Curve::Match
345 (const Quantity_Length X,
346 const Quantity_Length Y,
347 const Quantity_Length Z,
348 const Quantity_Length aDistance,
349 const Adaptor3d_Curve& aCurve,
350 const Quantity_Length aDeflection,
351 const Standard_Real aLimit,
352 const Standard_Integer NbPoints)
354 Standard_Real V1, V2;
355 FindLimits(aCurve, aLimit, V1, V2);
357 return MatchCurve(X,Y,Z,aDistance,aCurve,
358 aDeflection,NbPoints,V1,V2);
362 //==================================================================
365 //==================================================================
366 Standard_Boolean StdPrs_Curve::Match
367 (const Quantity_Length X,
368 const Quantity_Length Y,
369 const Quantity_Length Z,
370 const Quantity_Length aDistance,
371 const Adaptor3d_Curve& aCurve,
372 const Standard_Real U1,
373 const Standard_Real U2,
374 const Handle (Prs3d_Drawer)& aDrawer)
376 Standard_Real V1 = U1;
377 Standard_Real V2 = U2;
379 if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
380 if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
382 return MatchCurve(X,Y,Z,aDistance,aCurve,
383 aDrawer->MaximalChordialDeviation(),
384 aDrawer->Discretisation(),V1,V2);
388 //==================================================================
391 //==================================================================
392 Standard_Boolean StdPrs_Curve::Match
393 (const Quantity_Length X,
394 const Quantity_Length Y,
395 const Quantity_Length Z,
396 const Quantity_Length aDistance,
397 const Adaptor3d_Curve& aCurve,
398 const Standard_Real U1,
399 const Standard_Real U2,
400 const Quantity_Length aDeflection,
401 const Standard_Integer aNbPoints)
403 return MatchCurve(X,Y,Z,aDistance,aCurve,aDeflection,aNbPoints,U1,U2);