]> SALOME platform Git repositories - modules/geom.git/blob - src/OBJECT/GEOM_OCCReader.cxx
Salome HOME
Porting to OCCT development version: Standard_PI -> M_PI
[modules/geom.git] / src / OBJECT / GEOM_OCCReader.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 //  GEOM OBJECT : interactive object for Geometry entities visualization
23 //  File   : GEOM_OCCReader.h
24 //  Author : Christophe ATTANASIO
25 //  Module : GEOM
26
27 #include "GEOM_OCCReader.h"
28
29 // VTK Includes
30 #include <vtkPoints.h>
31 #include <vtkCellArray.h>
32
33 #include <vtkObjectFactory.h>
34 #include <vtkPolyData.h>
35
36 // OpenCASCADE Includes
37 #include <TopExp_Explorer.hxx>
38 #include <Poly_Triangulation.hxx>
39 #include <Poly_Polygon3D.hxx>
40 #include <Poly_PolygonOnTriangulation.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopAbs.hxx>
44 #include <Precision.hxx>
45 #include <BRepTools.hxx>
46 #include <BRep_Tool.hxx>
47 #include <Geom2dAdaptor_Curve.hxx>
48 #include <Geom2dHatch_Intersector.hxx>
49 #include <Geom2dHatch_Hatcher.hxx>
50 #include <Geom2d_Curve.hxx>
51 #include <Geom2d_Line.hxx>
52 #include <Geom2d_TrimmedCurve.hxx>
53 #include <HatchGen_Domain.hxx>
54 #include <TopAbs_ShapeEnum.hxx>
55 #include <gp_Dir2d.hxx>
56 #include <gp_Pnt2d.hxx>
57 #include <TColStd_Array1OfInteger.hxx>
58 #include <TColStd_Array1OfReal.hxx>
59 #include <Adaptor3d_HCurve.hxx>
60
61 #include "utilities.h"
62
63
64 #define MAX2(X, Y)      (  Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
65 #define MAX3(X, Y, Z)   ( MAX2 ( MAX2(X,Y) , Z) )
66
67 // Constante for iso building
68 static Standard_Real IntersectorConfusion = 1.e-10 ; // -8 ;
69 static Standard_Real IntersectorTangency  = 1.e-10 ; // -8 ;
70 static Standard_Real HatcherConfusion2d   = 1.e-8 ;
71 static Standard_Real HatcherConfusion3d   = 1.e-8 ;
72
73 static Standard_Integer lastVTKpoint = 0;
74 static Standard_Integer PlotCount = 0;
75 static Standard_Real IsoRatio = 1.001;
76 static Standard_Integer MaxPlotCount = 5; 
77
78 //=======================================================================
79 // Function : New
80 // Purpose  : 
81 //=======================================================================
82
83 GEOM_OCCReader* GEOM_OCCReader::New()
84 {
85   vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_OCCReader");
86   if(ret) {
87     return (GEOM_OCCReader*)ret;
88   }
89   return new GEOM_OCCReader;
90 }
91
92 //=======================================================================
93 // Function : GEOM_OCCReader
94 // Purpose  : 
95 //=======================================================================
96
97 GEOM_OCCReader::GEOM_OCCReader()
98 {
99   //this->myShape = NULL;
100   this->amode = 0;
101   this->forced = Standard_False;
102   this->discretiso = 15;
103   this->nbisos = 1;
104 }
105 //=======================================================================
106 // Function : ~GEOM_OCCReader
107 // Purpose  : 
108 //=======================================================================
109
110 GEOM_OCCReader::~GEOM_OCCReader()
111 {
112 }
113
114
115 //=======================================================================
116 // Function : Execute
117 // Purpose  : 
118 //=======================================================================
119
120
121 void GEOM_OCCReader::Execute() {
122
123   vtkPolyData* output = this->GetOutput();
124   vtkPoints* Pts = NULL;
125   vtkCellArray* Cells = NULL;
126   TopLoc_Location aLoc;
127
128   // Allocation
129   Pts = vtkPoints::New();
130   Cells = vtkCellArray::New();
131         
132   //Compute number of triangles and points
133   Standard_Integer nbpoly=0,nbpts=0;
134
135   if(amode==1) {
136     //for shading
137     
138     if(myShape.ShapeType() == TopAbs_FACE) {
139       // whole FACE 
140       const TopoDS_Face& aFace = TopoDS::Face(myShape);
141       Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
142       if(aPoly.IsNull()) {
143         Pts->Delete();
144         Cells->Delete();
145         return;
146       }
147
148       nbpts = aPoly->NbNodes();
149       nbpoly = aPoly->NbTriangles();
150
151       Pts->SetNumberOfPoints(nbpts);
152       Cells->Allocate(Cells->EstimateSize(nbpoly,3));
153     }
154     else { 
155         Cells->Delete();
156         Pts->Delete();
157         return; 
158     }
159   }
160
161   // Start computation
162   if(amode == 0) {
163     ComputeWireframe(Pts,Cells);
164     output->SetPoints(Pts);
165     output->SetLines(Cells);
166     output->Squeeze();
167   }
168   else {
169     if(myShape.ShapeType() == TopAbs_FACE) {
170       ComputeShading(Pts,Cells);
171
172       output->SetPoints(Pts);
173       output->SetPolys(Cells);
174       output->Squeeze();
175     }
176   }
177   Pts->Delete();
178   Cells->Delete();
179   
180 }
181
182 //=======================================================================
183 // Function : ComputeWireframe
184 // Purpose  : Compute the shape in CAD wireframe mode
185 //=======================================================================
186
187 void GEOM_OCCReader::ComputeWireframe(vtkPoints* Pts,vtkCellArray* Cells){
188
189   // Check the type of the shape:
190   if(myShape.ShapeType() == TopAbs_FACE) {
191     // Face
192     TransferFaceWData(TopoDS::Face(myShape),Pts,Cells);
193   } else if(myShape.ShapeType() == TopAbs_EDGE) {
194     // Edge
195     TransferEdgeWData(TopoDS::Edge(myShape),Pts,Cells);
196   } else {
197     if(myShape.ShapeType() == TopAbs_VERTEX) {
198       // Vertex
199       TransferVertexWData(TopoDS::Vertex(myShape),Pts,Cells);
200     }
201   }
202 }
203
204 //=======================================================================
205 // Function : TransferFaceWData
206 // Purpose  : Transfert wireframe data for FACE
207 //=======================================================================
208
209 void GEOM_OCCReader::TransferFaceWData(const TopoDS_Face& aFace,
210                                          vtkPoints* Pts,
211                                          vtkCellArray* Cells) 
212 {
213   TopoDS_Face aCopyFace = aFace; 
214   aCopyFace.Orientation (TopAbs_FORWARD);
215   createISO(aCopyFace,Precision::Infinite(),1,Pts,Cells);
216 }
217
218 //=======================================================================
219 // Function : createISO
220 // Purpose  : Create ISO for Face Wireframe representation 
221 //=======================================================================
222
223 void GEOM_OCCReader::createISO (const TopoDS_Face&     TopologicalFace,
224                                   const Standard_Real    Infinite,
225                                   const Standard_Integer NbIsos,
226                                   vtkPoints* Pts,
227                                   vtkCellArray* Cell)
228 {
229   Geom2dHatch_Hatcher aHatcher (Geom2dHatch_Intersector (IntersectorConfusion,
230                                                          IntersectorTangency),
231                                 HatcherConfusion2d,
232                                 HatcherConfusion3d,
233                                 Standard_True,
234                                 Standard_False);
235   
236   Standard_Real myInfinite,myUMin,myUMax,myVMin,myVMax;
237   //myInfinite = Precision::Infinite();
238   myInfinite = 1e38; // VTK uses float numbers - Precision::Infinite() is double and can not be accepted.
239
240   Standard_Integer myNbDom;
241   TColStd_Array1OfReal myUPrm(1, NbIsos),myVPrm(1, NbIsos);
242   TColStd_Array1OfInteger myUInd(1, NbIsos),myVInd(1, NbIsos);
243
244   myUInd.Init(0);
245   myVInd.Init(0);
246
247   //-----------------------------------------------------------------------
248   // If the Min Max bounds are infinite, there are bounded to Infinite
249   // value.
250   //-----------------------------------------------------------------------
251
252   BRepTools::UVBounds (TopologicalFace, myUMin, myUMax, myVMin, myVMax) ;
253   Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (myUMin) ;
254   Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (myUMax) ;
255   Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (myVMin) ;
256   Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (myVMax) ;
257   if (InfiniteUMin && InfiniteUMax) {
258     myUMin = - myInfinite ;
259     myUMax =   myInfinite ;
260   } else if (InfiniteUMin) {
261     myUMin = myUMax - myInfinite ;
262   } else if (InfiniteUMax) {
263     myUMax = myUMin + myInfinite ;
264   }
265   if (InfiniteVMin && InfiniteVMax) {
266     myVMin = - myInfinite ;
267     myVMax =   myInfinite ;
268   } else if (InfiniteVMin) {
269     myVMin = myVMax - myInfinite ;
270   } else if (InfiniteVMax) {
271     myVMax = myVMin + myInfinite ;
272   }
273
274   //-----------------------------------------------------------------------
275   // Retreiving the edges and loading them into the hatcher.
276   //-----------------------------------------------------------------------
277
278   TopExp_Explorer ExpEdges ;
279   for (ExpEdges.Init (TopologicalFace, TopAbs_EDGE) ; ExpEdges.More() ; ExpEdges.Next()) {
280     const TopoDS_Edge& TopologicalEdge = TopoDS::Edge (ExpEdges.Current()) ;
281     Standard_Real U1, U2 ;
282     const Handle(Geom2d_Curve) PCurve = BRep_Tool::CurveOnSurface (TopologicalEdge, TopologicalFace, U1, U2) ;
283
284     if ( PCurve.IsNull() ) {
285       return;
286     }
287
288     if ( U1==U2) {
289       return;
290     }
291
292     //-- Test if a TrimmedCurve is necessary
293     if(   Abs(PCurve->FirstParameter()-U1)<= Precision::PConfusion() 
294           && Abs(PCurve->LastParameter()-U2)<= Precision::PConfusion()) { 
295       aHatcher.AddElement (PCurve, TopologicalEdge.Orientation()) ;      
296     }
297     else { 
298       if (!PCurve->IsPeriodic()) {
299         Handle (Geom2d_TrimmedCurve) TrimPCurve =Handle(Geom2d_TrimmedCurve)::DownCast(PCurve);
300         if (!TrimPCurve.IsNull()) {
301           if (TrimPCurve->BasisCurve()->FirstParameter()-U1 > Precision::PConfusion() ||
302               U2-TrimPCurve->BasisCurve()->LastParameter()  > Precision::PConfusion()) {
303             aHatcher.AddElement (PCurve, TopologicalEdge.Orientation()) ;      
304             return;
305           }
306         }
307         else {
308           if (PCurve->FirstParameter()-U1 > Precision::PConfusion()){
309             U1=PCurve->FirstParameter();
310           }
311           if (U2-PCurve->LastParameter()  > Precision::PConfusion()){
312             U2=PCurve->LastParameter();
313           }
314         }
315       }
316       Handle (Geom2d_TrimmedCurve) TrimPCurve = new Geom2d_TrimmedCurve (PCurve, U1, U2) ;
317       aHatcher.AddElement (TrimPCurve, TopologicalEdge.Orientation()) ;
318     }
319   }
320
321
322   //-----------------------------------------------------------------------
323   // Loading and trimming the hatchings.
324   //-----------------------------------------------------------------------
325
326   Standard_Integer IIso ;
327   Standard_Real DeltaU = Abs (myUMax - myUMin) ;
328   Standard_Real DeltaV = Abs (myVMax - myVMin) ;
329   Standard_Real confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d ;
330   aHatcher.Confusion3d (confusion) ;
331
332   Standard_Real StepU = DeltaU / (Standard_Real) NbIsos ;
333   if (StepU > confusion) {
334     Standard_Real UPrm = myUMin + StepU / 2. ;
335     gp_Dir2d Dir (0., 1.) ;
336     for (IIso = 1 ; IIso <= NbIsos ; IIso++) {
337       myUPrm(IIso) = UPrm ;
338       gp_Pnt2d Ori (UPrm, 0.) ;
339       Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ;
340       myUInd(IIso) = aHatcher.AddHatching (HCur) ;
341       UPrm += StepU ;
342     }
343   }
344
345   Standard_Real StepV = DeltaV / (Standard_Real) NbIsos ;
346   if (StepV > confusion) {
347     Standard_Real VPrm = myVMin + StepV / 2. ;
348     gp_Dir2d Dir (1., 0.) ;
349     for (IIso = 1 ; IIso <= NbIsos ; IIso++) {
350       myVPrm(IIso) = VPrm ;
351       gp_Pnt2d Ori (0., VPrm) ;
352       Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ;
353       myVInd(IIso) = aHatcher.AddHatching (HCur) ;
354       VPrm += StepV ;
355     }
356   }
357
358   //-----------------------------------------------------------------------
359   // Computation.
360   //-----------------------------------------------------------------------
361
362   aHatcher.Trim() ;
363
364   myNbDom = 0 ;
365   for (IIso = 1 ; IIso <= NbIsos ; IIso++) {
366     Standard_Integer Index ;
367
368     Index = myUInd(IIso) ;
369     if (Index != 0) {
370       if (aHatcher.TrimDone (Index) && !aHatcher.TrimFailed (Index)) {
371         aHatcher.ComputeDomains (Index);
372         if (aHatcher.IsDone (Index)) myNbDom = myNbDom + aHatcher.NbDomains (Index) ;
373       }
374     }
375
376     Index = myVInd(IIso) ;
377     if (Index != 0) {
378       if (aHatcher.TrimDone (Index) && !aHatcher.TrimFailed (Index)) {
379         aHatcher.ComputeDomains (Index);
380         if (aHatcher.IsDone (Index)) myNbDom = myNbDom + aHatcher.NbDomains (Index) ;
381       }
382     }
383   }
384
385   //-----------------------------------------------------------------------
386   // Push iso lines in vtk kernel
387   //-----------------------------------------------------------------------
388
389
390   Standard_Integer pt_start_idx = 0;
391
392   for (Standard_Integer UIso = myUPrm.Lower() ; UIso <= myUPrm.Upper() ; UIso++) {
393     Standard_Integer UInd = myUInd.Value (UIso) ;
394     if (UInd != 0) {
395       Standard_Real UPrm = myUPrm.Value (UIso) ;
396       if (!aHatcher.IsDone (UInd)) {
397         MESSAGE("DBRep_IsoBuilder:: U iso of parameter: "<<UPrm)
398         switch (aHatcher.Status (UInd)) {
399         case HatchGen_NoProblem          : MESSAGE("No Problem")          ; break ;
400         case HatchGen_TrimFailure        : MESSAGE("Trim Failure")        ; break ;
401         case HatchGen_TransitionFailure  : MESSAGE("Transition Failure")  ; break ;
402         case HatchGen_IncoherentParity   : MESSAGE("Incoherent Parity")   ; break ;
403         case HatchGen_IncompatibleStates : MESSAGE("Incompatible States") ; break ;
404         }
405       } else {
406         Standard_Integer NbDom = aHatcher.NbDomains (UInd) ;
407         for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++) {
408           const HatchGen_Domain& Dom = aHatcher.Domain (UInd, IDom) ;
409           Standard_Real V1 = Dom.HasFirstPoint()  ? Dom.FirstPoint().Parameter()  : myVMin - myInfinite ;
410           Standard_Real V2 = Dom.HasSecondPoint() ? Dom.SecondPoint().Parameter() : myVMax + myInfinite ;
411           DrawIso(GeomAbs_IsoU, UPrm, V1, V2, Pts, Cell,pt_start_idx);
412         }
413       }
414     }
415   }
416
417   for (Standard_Integer VIso = myVPrm.Lower() ; VIso <= myVPrm.Upper() ; VIso++) {
418     Standard_Integer VInd = myVInd.Value (VIso) ;
419     if (VInd != 0) {
420       Standard_Real VPrm = myVPrm.Value (VIso) ;
421       if (!aHatcher.IsDone (VInd)) {
422         MESSAGE("DBRep_IsoBuilder:: V iso of parameter: "<<VPrm)
423         switch (aHatcher.Status (VInd)) {
424         case HatchGen_NoProblem          : MESSAGE("No Problem")          ; break ;
425         case HatchGen_TrimFailure        : MESSAGE("Trim Failure")        ; break ;
426         case HatchGen_TransitionFailure  : MESSAGE("Transition Failure")  ; break ;
427         case HatchGen_IncoherentParity   : MESSAGE("Incoherent Parity")   ; break ;
428         case HatchGen_IncompatibleStates : MESSAGE("Incompatible States") ; break ;
429         }
430       } else {
431         Standard_Integer NbDom = aHatcher.NbDomains (VInd) ;
432         for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++) {
433           const HatchGen_Domain& Dom = aHatcher.Domain (VInd, IDom) ;
434           Standard_Real U1 = Dom.HasFirstPoint()  ? Dom.FirstPoint().Parameter()  : myVMin - myInfinite ;
435           Standard_Real U2 = Dom.HasSecondPoint() ? Dom.SecondPoint().Parameter() : myVMax + myInfinite ;
436           DrawIso(GeomAbs_IsoV, VPrm, U1, U2, Pts, Cell,pt_start_idx) ;
437         }
438       }
439     }
440   }
441
442 }
443
444 //=======================================================================
445 // Function : MoveTo
446 // Purpose  : Init VTK ISO PLOT
447 //=======================================================================
448 void GEOM_OCCReader::MoveTo(gp_Pnt P,
449                               vtkPoints* Pts)
450 {    
451   float coord[3];
452
453   coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
454   lastVTKpoint = Pts->InsertNextPoint(coord);
455     
456
457
458 //=======================================================================
459 // Function : DrawTo
460 // Purpose  : Plot point in VTK
461 //=======================================================================
462 void GEOM_OCCReader::DrawTo(gp_Pnt P,
463                               vtkPoints* Pts,
464                               vtkCellArray* Cells)
465 {
466   float coord[3];
467   coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
468   Standard_Integer NewVTKpoint =  Pts->InsertNextPoint(coord);
469
470   vtkIdType pts[2];
471   pts[0] = lastVTKpoint;
472   pts[1] = NewVTKpoint;
473
474   Cells->InsertNextCell(2,pts);
475     
476   lastVTKpoint = NewVTKpoint;
477 }
478
479
480 //=======================================================================
481 // Function : DrawIso
482 // Purpose  : Draw an iso on vtk
483 //=======================================================================
484 void GEOM_OCCReader::DrawIso(GeomAbs_IsoType T, 
485                                Standard_Real Par, 
486                                Standard_Real T1,
487                                Standard_Real T2,
488                                vtkPoints* Pts,
489                                vtkCellArray* Cells,
490                                Standard_Integer& startidx)
491 {
492
493   Standard_Boolean halt = Standard_False;
494   Standard_Integer j,myDiscret = discretiso;
495   Standard_Real U1,U2,V1,V2,stepU=0.,stepV=0.;
496   gp_Pnt P;
497   TopLoc_Location l;
498
499   const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(myShape),l);
500   if (!S.IsNull()) {
501     BRepAdaptor_Surface S(TopoDS::Face(myShape),Standard_False);
502       
503     GeomAbs_SurfaceType SurfType = S.GetType();
504
505     GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
506
507     Standard_Integer Intrv, nbIntv;
508     Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
509     Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
510     TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
511
512
513     if (T == GeomAbs_IsoU) {
514       S.VIntervals(TI, GeomAbs_CN);
515       V1 = Max(T1, TI(1));
516       V2 = Min(T2, TI(2));
517       U1 = Par;
518       U2 = Par;
519       stepU = 0;
520       nbIntv = nbVIntv;
521     }
522     else {
523       S.UIntervals(TI, GeomAbs_CN);
524       U1 = Max(T1, TI(1));
525       U2 = Min(T2, TI(2));
526       V1 = Par;
527       V2 = Par;
528       stepV = 0;
529       nbIntv = nbUIntv;
530     }   
531         
532     S.D0(U1,V1,P);
533     MoveTo(P,Pts);
534
535     for (Intrv = 1; Intrv <= nbIntv; Intrv++) {
536
537       if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
538         continue;
539       if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
540         continue;
541       if (T == GeomAbs_IsoU) {
542         V1 = Max(T1, TI(Intrv));
543         V2 = Min(T2, TI(Intrv + 1));
544         stepV = (V2 - V1) / myDiscret;
545       }
546       else {
547         U1 = Max(T1, TI(Intrv));
548         U2 = Min(T2, TI(Intrv + 1));
549         stepU = (U2 - U1) / myDiscret;
550       }
551
552       switch (SurfType) {
553         //-------------GeomAbs_Plane---------------
554       case GeomAbs_Plane :
555         break;
556         //----GeomAbs_Cylinder   GeomAbs_Cone------
557       case GeomAbs_Cylinder :
558       case GeomAbs_Cone :
559         if (T == GeomAbs_IsoV) {
560           for (j = 1; j < myDiscret; j++) {
561             U1 += stepU;
562             V1 += stepV;
563             S.D0(U1,V1,P);
564             DrawTo(P,Pts,Cells);
565           }
566         }
567         break;
568         //---GeomAbs_Sphere   GeomAbs_Torus--------
569         //GeomAbs_BezierSurface GeomAbs_BezierSurface
570       case GeomAbs_Sphere :
571       case GeomAbs_Torus :
572       case GeomAbs_OffsetSurface :
573       case GeomAbs_OtherSurface :
574         for (j = 1; j < myDiscret; j++) {
575           U1 += stepU;
576           V1 += stepV;
577           S.D0(U1,V1,P);
578           DrawTo(P,Pts,Cells);
579         }
580         break;
581         //-------------GeomAbs_BSplineSurface------
582       case GeomAbs_BezierSurface :
583       case GeomAbs_BSplineSurface :
584         for (j = 1; j <= myDiscret/2; j++) {
585
586           PlotCount = 0;
587
588           PlotIso ( S, T, U1, V1, (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells);
589           U1 += stepU*2.;
590           V1 += stepV*2.;
591         }
592         break;
593         //-------------GeomAbs_SurfaceOfExtrusion--
594         //-------------GeomAbs_SurfaceOfRevolution-
595       case GeomAbs_SurfaceOfExtrusion :
596       case GeomAbs_SurfaceOfRevolution :
597         if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
598             (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion)) {
599           if (SurfType == GeomAbs_SurfaceOfExtrusion) break;
600           for (j = 1; j < myDiscret; j++) {
601             U1 += stepU;
602             V1 += stepV;
603             S.D0(U1,V1,P);
604             DrawTo(P,Pts,Cells);
605           }
606         } else {
607           CurvType = (S.BasisCurve())->GetType();
608           switch (CurvType) {
609           case GeomAbs_Line :
610             break;
611           case GeomAbs_Circle :
612           case GeomAbs_Ellipse :
613             for (j = 1; j < myDiscret; j++) {
614               U1 += stepU;
615               V1 += stepV;
616               S.D0(U1,V1,P);
617               DrawTo(P,Pts,Cells);
618             }
619             break;
620           case GeomAbs_Parabola :
621           case GeomAbs_Hyperbola :
622           case GeomAbs_BezierCurve :
623           case GeomAbs_BSplineCurve :
624           case GeomAbs_OtherCurve :
625             for (j = 1; j <= myDiscret/2; j++) {
626
627               PlotCount = 0;
628
629               PlotIso ( S, T, U1, V1,(T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells);
630               U1 += stepU*2.;
631               V1 += stepV*2.;
632             }
633             break;
634           }
635         }
636       }
637     }
638     S.D0(U2,V2,P);
639     DrawTo(P,Pts,Cells);
640   }  
641 }
642
643 //=======================================================================
644 // Function : PlotIso
645 // Purpose  : Plot iso for other surface
646 //=======================================================================
647
648 void GEOM_OCCReader::PlotIso (BRepAdaptor_Surface& S, 
649                                 GeomAbs_IsoType T,
650                                 Standard_Real& U, 
651                                 Standard_Real& V, 
652                                 Standard_Real Step, 
653                                 Standard_Boolean& halt,
654                                 vtkPoints* Pts,
655                                 vtkCellArray* Cells)
656 {
657
658   ++PlotCount; 
659
660   gp_Pnt Pl, Pr, Pm;
661
662   if (T == GeomAbs_IsoU) {
663     S.D0(U, V, Pl);
664     S.D0(U, V + Step/2., Pm);
665     S.D0(U, V + Step, Pr);
666   } else {
667     S.D0(U, V, Pl);
668     S.D0(U + Step/2., V, Pm);
669     S.D0(U + Step, V, Pr);
670   }
671
672   if (PlotCount > MaxPlotCount) {
673     DrawTo(Pr,Pts,Cells);
674     return;
675   }
676
677   if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio*Pl.Distance(Pr)) {
678     DrawTo(Pr,Pts,Cells);
679   } else 
680     if (T == GeomAbs_IsoU) {
681       PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells);
682       Standard_Real aLocalV = V + Step/2 ;
683       PlotIso ( S, T, U, aLocalV , Step/2, halt, Pts, Cells);
684     } else {
685       PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells);
686       Standard_Real aLocalU = U + Step/2 ;
687       PlotIso ( S, T, aLocalU , V, Step/2, halt, Pts, Cells);
688     }
689 }
690
691 //=======================================================================
692 // Function : TransferEdgeWData
693 // Purpose  : Transfert wireframe data for EDGE
694 //=======================================================================
695
696 void GEOM_OCCReader::TransferEdgeWData(const TopoDS_Edge& aEdge,
697                                          vtkPoints* Pts,
698                                          vtkCellArray* Cells) {
699   
700   
701   Handle(Poly_PolygonOnTriangulation) aEdgePoly;
702   Standard_Integer i = 1;
703   Handle(Poly_Triangulation) T;
704   TopLoc_Location aEdgeLoc;
705   BRep_Tool::PolygonOnTriangulation(aEdge, aEdgePoly, T, aEdgeLoc, i);
706   
707   Handle(Poly_Polygon3D) P;
708   if(aEdgePoly.IsNull()) {
709     P = BRep_Tool::Polygon3D(aEdge, aEdgeLoc);
710   }
711
712   if(P.IsNull() && aEdgePoly.IsNull())
713     return;
714   
715   // Location edges
716   //---------------
717   
718   gp_Trsf edgeTransf;
719   Standard_Boolean isidtrsf = true;
720   if(!aEdgeLoc.IsIdentity())  {
721     isidtrsf = false;
722     edgeTransf = aEdgeLoc.Transformation();
723   }
724
725   gp_Pnt aP1, aP2;
726
727   Standard_Integer nbnodes;
728   if (aEdgePoly.IsNull()) {
729     nbnodes = P->NbNodes();
730     const TColgp_Array1OfPnt& theNodesP = P->Nodes();
731
732     aP1 = theNodesP(1);
733     aP2 = theNodesP(nbnodes);
734
735     float coord[3];
736     vtkIdType pts[2];
737
738     for(int j=1;j<nbnodes;j++) {
739       gp_Pnt pt1 = theNodesP(j);
740       gp_Pnt pt2 = theNodesP(j+1);
741     
742       if(!isidtrsf) {
743         // apply edge transformation
744         pt1.Transform(edgeTransf);
745         pt2.Transform(edgeTransf);
746       }
747       
748       // insert pt1
749       coord[0] = pt1.X(); coord[1] = pt1.Y(); coord[2] = pt1.Z();
750       pts[0] = Pts->InsertNextPoint(coord);
751       
752       // insert pt2
753       coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z();
754       pts[1] = Pts->InsertNextPoint(coord);
755       
756       // insert line (pt1,pt2)
757       Cells->InsertNextCell(2,pts);
758     }
759   } else {
760     nbnodes = aEdgePoly->NbNodes();
761     const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes();
762     const TColgp_Array1OfPnt& theNodesPoly = T->Nodes();
763
764     aP1 = theNodesPoly(1);
765     aP2 = theNodesPoly(nbnodes);
766
767     float coord[3];
768     vtkIdType pts[2];
769     
770     for(int j=1;j<nbnodes;j++) {
771       Standard_Integer id1 = Nodesidx(j);
772       Standard_Integer id2 = Nodesidx(j+1);
773       
774       gp_Pnt pt1 = theNodesPoly(id1);
775       gp_Pnt pt2 = theNodesPoly(id2);
776           
777       if(!isidtrsf) {
778         // apply edge transformation
779         pt1.Transform(edgeTransf);
780         pt2.Transform(edgeTransf);
781       }
782       
783       // insert pt1
784       coord[0] = pt1.X(); coord[1] = pt1.Y(); coord[2] = pt1.Z();
785       pts[0] = Pts->InsertNextPoint(coord);
786       
787       // insert pt2
788       coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z();
789       pts[1] = Pts->InsertNextPoint(coord);
790       
791       // insert line (pt1,pt2)
792       Cells->InsertNextCell(2,pts);
793     }
794   }
795
796   // vector representation has an arrow on its end
797   if (myIsVector)
798   {
799     if (!isidtrsf) {
800       // apply edge transformation
801       aP1.Transform(edgeTransf);
802       aP2.Transform(edgeTransf);
803     }
804
805     // draw an arrow
806     gp_Vec aDirVec (aP1, aP2);
807     Standard_Real aDist = aDirVec.Magnitude();
808     if (aDist < gp::Resolution()) return;
809     gp_Dir aDirection (aDirVec);
810
811     Standard_Real anAngle = M_PI/180. * 5.;
812     Standard_Real aLength = aDist/10.;
813
814     Standard_Real dx,dy,dz;
815     aDirection.Coord(dx,dy,dz);
816
817     // Pointe de la fleche
818     Standard_Real xo,yo,zo;
819     aP2.Coord(xo,yo,zo);
820
821     // Centre du cercle base de la fleche
822     gp_XYZ aPc = aP2.XYZ() - aDirection.XYZ() * aLength;
823
824     // Construction d'un repere i,j pour le cercle
825     gp_Dir aDirN;
826     if      (Abs(dx) <= Abs(dy) && Abs(dx) <= Abs(dz)) aDirN = gp::DX();
827     else if (Abs(dy) <= Abs(dz) && Abs(dy) <= Abs(dx)) aDirN = gp::DY();
828     else aDirN = gp::DZ();
829
830     gp_Dir aDirI = aDirection ^ aDirN;
831     gp_Dir aDirJ = aDirection ^ aDirI;
832
833     // Add points and segments, composing the arrow
834     Standard_Real cosinus, sinus, Tg = tan(anAngle);
835
836     float coord[3];
837     coord[0] = xo; coord[1] = yo; coord[2] = zo;
838
839     int ptLoc = Pts->InsertNextPoint(coord);
840     int ptFirst = 0;
841     int ptPrev = 0;
842     int ptCur = 0;
843
844     vtkIdType pts[2];
845
846     int NbPoints = 15;
847     for (int i = 1; i <= NbPoints; i++, ptPrev = ptCur)
848     {
849       cosinus = cos(2. * M_PI / NbPoints * (i-1));   
850       sinus   = sin(2. * M_PI / NbPoints * (i-1));
851
852       gp_XYZ aP = aPc + (aDirI.XYZ() * cosinus + aDirJ.XYZ() * sinus) * aLength * Tg;
853       coord[0] = aP.X();
854       coord[1] = aP.Y();
855       coord[2] = aP.Z();
856
857       // insert pts
858       ptCur = Pts->InsertNextPoint(coord);
859       pts[0] = ptCur;
860
861       if (i == 1) {
862         ptFirst = ptCur;
863       }
864       else {
865         // insert line (ptCur,ptPrev)
866         pts[1] = ptPrev;
867         Cells->InsertNextCell(2,pts);
868       }
869
870       // insert line (ptCur,ptLoc)
871       pts[1] = ptLoc;
872       Cells->InsertNextCell(2,pts);
873     }
874
875     // insert line (ptCur,ptFirst)
876     pts[0] = ptCur;
877     pts[1] = ptFirst;
878     Cells->InsertNextCell(2,pts);
879   }
880 }
881
882 /*  Standard_Integer nbnodes = aEdgePoly->NbNodes();
883   const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes();
884   const TColgp_Array1OfPnt& theNodes = T->Nodes();
885     
886   float coord[3];
887   vtkIdType pts[2];
888     
889
890   // PUSH NODES
891   for(i=1;i<=nbnodes;i++) {
892     Standard_Integer id = Nodesidx(i);
893     gp_Pnt pt = theNodes(id);
894  
895     float coord[3];
896     if(!isidtrsf) pt.Transform(edgeTransf);
897
898     coord[0] = pt.X(); coord[1] = pt.Y(); coord[2] = pt.Z();
899
900     Pts->SetPoint(id-1,coord);
901
902   }
903
904   // PUSH EDGES
905   for(i=1;i<nbnodes;i++) {
906       
907     Standard_Integer id1 = Nodesidx(i);
908     Standard_Integer id2 = Nodesidx(i+1);
909     
910     vtkIdType pts[2];
911     pts[0] = id1-1; pts[1] = id2-1;
912
913     // insert line (pt1,pt2)
914     Cells->InsertNextCell(2,pts);
915   }
916  
917   
918   }*/
919
920 //=======================================================================
921 // Function : TransferVertexWData
922 // Purpose  : Transfert wireframe data for VERTEX
923 //=======================================================================
924
925 void GEOM_OCCReader::TransferVertexWData(const TopoDS_Vertex& aVertex,
926                                          vtkPoints* Pts,
927                                          vtkCellArray* Cells) {
928 #define ZERO_COORD coord[0] = 0.0; coord[1] = 0.0; coord[2] = 0.0
929   
930   gp_Pnt P = BRep_Tool::Pnt( aVertex );
931   float delta = 1, coord[3];
932   vtkIdType pts[2];
933   // insert pt
934   ZERO_COORD; coord[0] = +delta;
935   pts[0] = Pts->InsertNextPoint(coord);
936   coord[0] = -delta;
937   pts[1] = Pts->InsertNextPoint(coord);
938   // insert line (pt1,pt2)
939   Cells->InsertNextCell(2,pts);
940
941   ZERO_COORD; coord[1] = +delta;
942   pts[0] = Pts->InsertNextPoint(coord);
943   coord[1] = -delta;
944   pts[1] = Pts->InsertNextPoint(coord);
945   // insert line (pt1,pt2)
946   Cells->InsertNextCell(2,pts);
947
948   ZERO_COORD; coord[2] = +delta;
949   pts[0] = Pts->InsertNextPoint(coord);
950   coord[2] = -delta;
951   pts[1] = Pts->InsertNextPoint(coord);
952   // insert line (pt1,pt2)
953   Cells->InsertNextCell(2,pts);
954
955 #undef ZERO_COORD
956 }       
957
958 //=======================================================================
959 // Function : TransferEdgeSData(
960 // Purpose  : Transfert shading data for EDGE
961 //=======================================================================
962
963 void GEOM_OCCReader::TransferEdgeSData(const TopoDS_Edge& aFace,
964                                          vtkPoints* Pts,
965                                          vtkCellArray* Cells) 
966 {
967 }
968
969
970 //=======================================================================
971 // Function : TransferFaceSData
972 // Purpose  : Transfert shading data for FACE
973 //=======================================================================
974 void GEOM_OCCReader::TransferFaceSData(const TopoDS_Face& aFace,
975                                          vtkPoints* Pts,
976                                          vtkCellArray* Cells) {
977
978   TopLoc_Location aLoc;
979   Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
980   if(aPoly.IsNull()) return;
981   else {
982     
983     gp_Trsf myTransf;
984     Standard_Boolean identity = true;
985     if(!aLoc.IsIdentity())  {
986       identity = false;
987       myTransf = aLoc.Transformation();
988     }
989
990     Standard_Integer nbNodesInFace = aPoly->NbNodes();
991     Standard_Integer nbTriInFace = aPoly->NbTriangles();
992                 
993     const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
994     const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
995       
996     Standard_Integer i;
997     for(i=1;i<=nbNodesInFace;i++) {
998       gp_Pnt P = Nodes(i);
999       float coord[3];
1000       if(!identity) P.Transform(myTransf);
1001       coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
1002       Pts->SetPoint(i-1,coord);
1003     }
1004
1005     for(i=1;i<=nbTriInFace;i++) {
1006       // Get the triangle
1007         
1008       Standard_Integer N1,N2,N3;
1009       Triangles(i).Get(N1,N2,N3);
1010         
1011       vtkIdType pts[3];
1012       pts[0] = N1-1; pts[1] = N2-1; pts[2] = N3-1;
1013       Cells->InsertNextCell(3,pts);
1014
1015     }
1016   } 
1017 }
1018
1019 //=======================================================================
1020 // Function : ComputeShading
1021 // Purpose  : Compute the shape in shading mode
1022 //=======================================================================
1023 void GEOM_OCCReader::ComputeShading(vtkPoints* Pts,vtkCellArray* Cells){
1024
1025   // Check the type of the shape:
1026   if(myShape.ShapeType() == TopAbs_FACE) {
1027     // Face
1028     TransferFaceSData(TopoDS::Face(myShape),Pts,Cells);
1029   }
1030   else {
1031     if(myShape.ShapeType() == TopAbs_EDGE) {
1032       // Edge
1033       TransferEdgeSData(TopoDS::Edge(myShape),Pts,Cells);
1034     }
1035     else {
1036     }
1037
1038   } 
1039
1040 }
1041
1042 //=======================================================================
1043 // Function : 
1044 // Purpose  : Set parameters
1045 //=======================================================================
1046 void GEOM_OCCReader::setDisplayMode(int thenewmode) {
1047   amode = thenewmode;
1048 }
1049
1050 void GEOM_OCCReader::setTopo(const TopoDS_Shape& aShape, bool isVector) {
1051   myShape = aShape;
1052   myIsVector = isVector;
1053 }
1054
1055 void GEOM_OCCReader::setForceUpdate(Standard_Boolean bol) {
1056   forced = bol;
1057 }
1058
1059 //=======================================================================
1060 // Function : 
1061 // Purpose  : Get parameters
1062 //=======================================================================
1063 const TopoDS_Shape& GEOM_OCCReader::getTopo() {
1064   return myShape;
1065 }
1066
1067 int GEOM_OCCReader::getDisplayMode() {
1068   return amode;
1069 }