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