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