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