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