1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <VrmlConverter_DeflectionCurve.ixx>
16 #include <gp_Circ.hxx>
19 #include <Bnd_Box.hxx>
20 #include <Precision.hxx>
21 #include <TColgp_HArray1OfVec.hxx>
22 #include <TColStd_HArray1OfInteger.hxx>
23 #include <Vrml_Material.hxx>
24 #include <VrmlConverter_LineAspect.hxx>
25 #include <Vrml_Separator.hxx>
26 #include <Vrml_Coordinate3.hxx>
27 #include <Vrml_IndexedLineSet.hxx>
28 #include <Precision.hxx>
29 #include <GCPnts_QuasiUniformDeflection.hxx>
30 #include <BndLib_Add3dCurve.hxx>
32 //==================================================================
33 // function: FindLimits
35 //==================================================================
36 static void FindLimits(const Adaptor3d_Curve& aCurve,
37 const Standard_Real aLimit,
41 First = aCurve.FirstParameter();
42 Last = aCurve.LastParameter();
43 Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
44 Standard_Boolean lastInf = Precision::IsPositiveInfinite(Last);
46 if (firstInf || lastInf) {
48 Standard_Real delta = 1;
49 if (firstInf && lastInf) {
56 } while (P1.Distance(P2) < aLimit);
64 } while (P1.Distance(P2) < aLimit);
72 } while (P1.Distance(P2) < aLimit);
78 //==================================================================
79 // function: PrintPoints
81 //==================================================================
82 static void PrintPoints (Handle(TColgp_HArray1OfVec)& aHAV1,
83 Handle(TColStd_HArray1OfInteger)& aHAI1,
84 const Handle(VrmlConverter_Drawer)& aDrawer,
85 Standard_OStream& anOStream)
87 // creation of Vrml objects
88 Handle(VrmlConverter_LineAspect) LA = new VrmlConverter_LineAspect;
89 LA = aDrawer->LineAspect();
95 if (LA->HasMaterial()){
97 Handle(Vrml_Material) M;
103 Handle(Vrml_Coordinate3) C3 = new Vrml_Coordinate3(aHAV1);
104 C3->Print(anOStream);
106 Vrml_IndexedLineSet ILS;
107 ILS.SetCoordIndex(aHAI1);
108 ILS.Print(anOStream);
110 SE1.Print(anOStream);
113 //==================================================================
114 // function: DrawCurve
116 //==================================================================
117 static void DrawCurve (Adaptor3d_Curve& aCurve,
118 const Standard_Real TheDeflection,
119 const Standard_Real U1,
120 const Standard_Real U2,
121 const Handle(VrmlConverter_Drawer)& aDrawer, // for passsing of LineAspect
122 Standard_OStream& anOStream)
125 Standard_Boolean key = Standard_False;
126 Handle(TColgp_HArray1OfVec) HAV1;
127 Handle(TColStd_HArray1OfInteger) HAI1;
129 switch (aCurve.GetType()) {
134 HAV1 = new TColgp_HArray1OfVec(1, 2);
135 HAI1 = new TColStd_HArray1OfInteger(1,3);
137 // array of coordinates of line
138 gp_Pnt p = aCurve.Value(U1);
139 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
142 p = aCurve.Value(U2);
143 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
146 // array of indexes of line
149 HAI1->SetValue(3,-1);
155 Standard_Real Radius = aCurve.Circle().Radius();
156 if (!Precision::IsInfinite(Radius)) {
157 Standard_Real DU = Sqrt(8.0 * TheDeflection / Radius);
158 Standard_Integer N = Standard_Integer(Abs( U2 - U1) / DU);
164 HAV1 = new TColgp_HArray1OfVec(1, N+1);
165 HAI1 = new TColStd_HArray1OfInteger(1,N+2);
171 for (Standard_Integer Index = 1; Index <= N+1; Index++) {
172 U = U1 + (Index - 1) * DU;
175 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
176 HAV1->SetValue(Index,V);
177 HAI1->SetValue(Index,Index-1);
181 if( HAV1->Value(1).IsEqual( HAV1->Value(N+1),Precision::Confusion(), Precision::Angular() ) )
183 HAI1->SetValue(N+1, 0);
186 HAI1->SetValue(HAI1->Upper(),-1);
194 GCPnts_QuasiUniformDeflection Algo(aCurve,TheDeflection,U1,U2);
197 Standard_Integer NumberOfPoints = Algo.NbPoints();
198 if (NumberOfPoints > 0) {
202 HAV1 = new TColgp_HArray1OfVec(1, NumberOfPoints);
203 HAI1 = new TColStd_HArray1OfInteger(1,NumberOfPoints+1);
206 for (i=1;i<=NumberOfPoints;i++) {
208 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
212 for (i=HAI1->Lower(); i < HAI1->Upper(); i++)
214 HAI1->SetValue(i,i-1);
216 HAI1->SetValue(HAI1->Upper(),-1);
221 //cannot draw with respect to a maximal chordial deviation
225 //cout << " Array HAI1 - coordIndex " << endl;
227 //for ( i=HAI1->Lower(); i <= HAI1->Upper(); i++ )
229 // cout << HAI1->Value(i) << endl;
234 PrintPoints(HAV1, HAI1, aDrawer, anOStream);
238 //==================================================================
239 // function: GetDeflection
241 //==================================================================
242 static Standard_Real GetDeflection(const Adaptor3d_Curve& aCurve,
243 const Standard_Real U1,
244 const Standard_Real U2,
245 const Handle(VrmlConverter_Drawer)& aDrawer) {
247 Standard_Real theRequestedDeflection;
248 if(aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE) // TOD_RELATIVE, TOD_ABSOLUTE
251 BndLib_Add3dCurve::Add(aCurve, U1, U2, Precision::Confusion(), box);
253 Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax, diagonal;
254 box.Get( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
255 if (!(box.IsOpenXmin() || box.IsOpenXmax() ||
256 box.IsOpenYmin() || box.IsOpenYmax() ||
257 box.IsOpenZmin() || box.IsOpenZmax()))
259 diagonal = Sqrt ((Xmax - Xmin)*( Xmax - Xmin) + ( Ymax - Ymin)*( Ymax - Ymin) + ( Zmax - Zmin)*( Zmax - Zmin));
260 diagonal = Max(diagonal, Precision::Confusion());
261 theRequestedDeflection = aDrawer->DeviationCoefficient() * diagonal;
266 theRequestedDeflection = aDrawer->DeviationCoefficient() * diagonal;
268 // cout << "diagonal = " << diagonal << endl;
269 // cout << "theRequestedDeflection = " << theRequestedDeflection << endl;
273 theRequestedDeflection = aDrawer->MaximalChordialDeviation();
275 return theRequestedDeflection;
277 //==================================================================
280 //==================================================================
281 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
282 Adaptor3d_Curve& aCurve,
283 const Handle(VrmlConverter_Drawer)& aDrawer)
286 Standard_Real V1, V2;
287 Standard_Real aLimit = aDrawer->MaximalParameterValue();
288 FindLimits(aCurve, aLimit, V1, V2);
290 Standard_Real theRequestedDeflection = GetDeflection(aCurve, V1, V2, aDrawer);
293 theRequestedDeflection,
294 V1 , V2, aDrawer, anOStream);
297 //==================================================================
300 //==================================================================
301 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
302 Adaptor3d_Curve& aCurve,
303 const Standard_Real U1,
304 const Standard_Real U2,
305 const Handle(VrmlConverter_Drawer)& aDrawer)
307 Standard_Real V1 = U1;
308 Standard_Real V2 = U2;
310 if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
311 if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
313 Standard_Real theRequestedDeflection = GetDeflection(aCurve, V1, V2, aDrawer);
315 theRequestedDeflection,
316 V1 , V2, aDrawer, anOStream);
319 //==================================================================
322 //==================================================================
324 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
325 Adaptor3d_Curve& aCurve,
326 const Standard_Real aDeflection,
327 const Standard_Real aLimit)
329 Standard_Real V1, V2;
330 FindLimits(aCurve, aLimit, V1, V2);
332 Handle(VrmlConverter_Drawer) aDrawer = new VrmlConverter_Drawer;
333 Handle(VrmlConverter_LineAspect) la = new VrmlConverter_LineAspect;
334 aDrawer->SetLineAspect(la);
338 V1 , V2, aDrawer, anOStream);
340 //==================================================================
343 //==================================================================
345 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
346 Adaptor3d_Curve& aCurve,
347 const Standard_Real aDeflection,
348 const Handle(VrmlConverter_Drawer)& aDrawer)
350 Standard_Real aLimit = aDrawer->MaximalParameterValue();
351 Standard_Real V1, V2;
352 FindLimits(aCurve, aLimit, V1, V2);
356 V1 , V2, aDrawer, anOStream);
358 //==================================================================
361 //==================================================================
363 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
364 Adaptor3d_Curve& aCurve,
365 const Standard_Real U1,
366 const Standard_Real U2,
367 const Standard_Real aDeflection)
369 Handle(VrmlConverter_Drawer) aDrawer = new VrmlConverter_Drawer;
370 Handle(VrmlConverter_LineAspect) la = new VrmlConverter_LineAspect;
371 aDrawer->SetLineAspect(la);
375 U1 , U2, aDrawer, anOStream);
378 //==================================================================
381 //==================================================================
383 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
384 const Adaptor3d_Curve& aCurve,
385 const Handle(TColStd_HArray1OfReal)& aParams,
386 const Standard_Integer aNbNodes,
387 const Handle(VrmlConverter_Drawer)& aDrawer)
389 Handle(TColgp_HArray1OfVec) aHAV1 = new TColgp_HArray1OfVec(1, aNbNodes);
390 Handle(TColStd_HArray1OfInteger) aHAI1 = new TColStd_HArray1OfInteger(1, aNbNodes + 1);
395 for (i = 1; i<=aNbNodes; i++)
397 Standard_Real aParam = aParams->Value(aParams->Lower() + i - 1);
398 aPoint = aCurve.Value(aParam);
399 aVec.SetX(aPoint.X());
400 aVec.SetY(aPoint.Y());
401 aVec.SetZ(aPoint.Z());
402 aHAV1->SetValue(i, aVec);
405 for (i = aHAI1->Lower(); i < aHAI1->Upper(); i++)
407 aHAI1->SetValue(i,i-1);
409 aHAI1->SetValue(aHAI1->Upper(),-1);
411 PrintPoints(aHAV1, aHAI1, aDrawer, anOStream);