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