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: DrawCurve
81 //==================================================================
82 static void DrawCurve (Adaptor3d_Curve& aCurve,
83 const Standard_Real TheDeflection,
84 const Standard_Real U1,
85 const Standard_Real U2,
86 const Handle(VrmlConverter_Drawer)& aDrawer, // for passsing of LineAspect
87 Standard_OStream& anOStream)
90 Standard_Boolean key = Standard_False;
91 Handle(TColgp_HArray1OfVec) HAV1;
92 Handle(TColStd_HArray1OfInteger) HAI1;
94 switch (aCurve.GetType()) {
99 HAV1 = new TColgp_HArray1OfVec(1, 2);
100 HAI1 = new TColStd_HArray1OfInteger(1,3);
102 // array of coordinates of line
103 gp_Pnt p = aCurve.Value(U1);
104 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
107 p = aCurve.Value(U2);
108 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
111 // array of indexes of line
114 HAI1->SetValue(3,-1);
120 Standard_Real Radius = aCurve.Circle().Radius();
121 if (!Precision::IsInfinite(Radius)) {
122 Standard_Real DU = Sqrt(8.0 * TheDeflection / Radius);
123 Standard_Integer N = Standard_Integer(Abs( U2 - U1) / DU);
129 HAV1 = new TColgp_HArray1OfVec(1, N+1);
130 HAI1 = new TColStd_HArray1OfInteger(1,N+2);
136 for (Standard_Integer Index = 1; Index <= N+1; Index++) {
137 U = U1 + (Index - 1) * DU;
140 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
141 HAV1->SetValue(Index,V);
142 HAI1->SetValue(Index,Index-1);
146 if( HAV1->Value(1).IsEqual( HAV1->Value(N+1),Precision::Confusion(), Precision::Angular() ) )
148 HAI1->SetValue(N+1, 0);
151 HAI1->SetValue(HAI1->Upper(),-1);
159 GCPnts_QuasiUniformDeflection Algo(aCurve,TheDeflection,U1,U2);
162 Standard_Integer NumberOfPoints = Algo.NbPoints();
163 if (NumberOfPoints > 0) {
167 HAV1 = new TColgp_HArray1OfVec(1, NumberOfPoints);
168 HAI1 = new TColStd_HArray1OfInteger(1,NumberOfPoints+1);
171 for (i=1;i<=NumberOfPoints;i++) {
173 V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
177 for (i=HAI1->Lower(); i < HAI1->Upper(); i++)
179 HAI1->SetValue(i,i-1);
181 HAI1->SetValue(HAI1->Upper(),-1);
186 //cannot draw with respect to a maximal chordial deviation
190 //cout << " Array HAI1 - coordIndex " << endl;
192 //for ( i=HAI1->Lower(); i <= HAI1->Upper(); i++ )
194 // cout << HAI1->Value(i) << endl;
200 // creation of Vrml objects
201 Handle(VrmlConverter_LineAspect) LA = new VrmlConverter_LineAspect;
202 LA = aDrawer->LineAspect();
206 SE1.Print(anOStream);
208 if (LA->HasMaterial()){
210 Handle(Vrml_Material) M;
216 Handle(Vrml_Coordinate3) C3 = new Vrml_Coordinate3(HAV1);
217 C3->Print(anOStream);
219 Vrml_IndexedLineSet ILS;
220 ILS.SetCoordIndex(HAI1);
221 ILS.Print(anOStream);
223 SE1.Print(anOStream);
226 //==================================================================
227 // function: GetDeflection
229 //==================================================================
230 static Standard_Real GetDeflection(const Adaptor3d_Curve& aCurve,
231 const Standard_Real U1,
232 const Standard_Real U2,
233 const Handle(VrmlConverter_Drawer)& aDrawer) {
235 Standard_Real theRequestedDeflection;
236 if(aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE) // TOD_RELATIVE, TOD_ABSOLUTE
239 BndLib_Add3dCurve::Add(aCurve, U1, U2, Precision::Confusion(), box);
241 Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax, diagonal;
242 box.Get( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
243 if (!(box.IsOpenXmin() || box.IsOpenXmax() ||
244 box.IsOpenYmin() || box.IsOpenYmax() ||
245 box.IsOpenZmin() || box.IsOpenZmax()))
247 diagonal = Sqrt ((Xmax - Xmin)*( Xmax - Xmin) + ( Ymax - Ymin)*( Ymax - Ymin) + ( Zmax - Zmin)*( Zmax - Zmin));
248 diagonal = Max(diagonal, Precision::Confusion());
249 theRequestedDeflection = aDrawer->DeviationCoefficient() * diagonal;
254 theRequestedDeflection = aDrawer->DeviationCoefficient() * diagonal;
256 // cout << "diagonal = " << diagonal << endl;
257 // cout << "theRequestedDeflection = " << theRequestedDeflection << endl;
261 theRequestedDeflection = aDrawer->MaximalChordialDeviation();
263 return theRequestedDeflection;
265 //==================================================================
268 //==================================================================
269 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
270 Adaptor3d_Curve& aCurve,
271 const Handle(VrmlConverter_Drawer)& aDrawer)
274 Standard_Real V1, V2;
275 Standard_Real aLimit = aDrawer->MaximalParameterValue();
276 FindLimits(aCurve, aLimit, V1, V2);
278 Standard_Real theRequestedDeflection = GetDeflection(aCurve, V1, V2, aDrawer);
281 theRequestedDeflection,
282 V1 , V2, aDrawer, anOStream);
285 //==================================================================
288 //==================================================================
289 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
290 Adaptor3d_Curve& aCurve,
291 const Standard_Real U1,
292 const Standard_Real U2,
293 const Handle(VrmlConverter_Drawer)& aDrawer)
295 Standard_Real V1 = U1;
296 Standard_Real V2 = U2;
298 if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
299 if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
301 Standard_Real theRequestedDeflection = GetDeflection(aCurve, V1, V2, aDrawer);
303 theRequestedDeflection,
304 V1 , V2, aDrawer, anOStream);
307 //==================================================================
310 //==================================================================
312 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
313 Adaptor3d_Curve& aCurve,
314 const Standard_Real aDeflection,
315 const Standard_Real aLimit)
317 Standard_Real V1, V2;
318 FindLimits(aCurve, aLimit, V1, V2);
320 Handle(VrmlConverter_Drawer) aDrawer = new VrmlConverter_Drawer;
321 Handle(VrmlConverter_LineAspect) la = new VrmlConverter_LineAspect;
322 aDrawer->SetLineAspect(la);
326 V1 , V2, aDrawer, anOStream);
328 //==================================================================
331 //==================================================================
333 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
334 Adaptor3d_Curve& aCurve,
335 const Standard_Real aDeflection,
336 const Handle(VrmlConverter_Drawer)& aDrawer)
338 Standard_Real aLimit = aDrawer->MaximalParameterValue();
339 Standard_Real V1, V2;
340 FindLimits(aCurve, aLimit, V1, V2);
344 V1 , V2, aDrawer, anOStream);
346 //==================================================================
349 //==================================================================
351 void VrmlConverter_DeflectionCurve::Add(Standard_OStream& anOStream,
352 Adaptor3d_Curve& aCurve,
353 const Standard_Real U1,
354 const Standard_Real U2,
355 const Standard_Real aDeflection)
357 Handle(VrmlConverter_Drawer) aDrawer = new VrmlConverter_Drawer;
358 Handle(VrmlConverter_LineAspect) la = new VrmlConverter_LineAspect;
359 aDrawer->SetLineAspect(la);
363 U1 , U2, aDrawer, anOStream);