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