Back to index

salome-geom  6.5.0
GEOM_OCCReader.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  GEOM OBJECT : interactive object for Geometry entities visualization
00024 //  File   : GEOM_OCCReader.h
00025 //  Author : Christophe ATTANASIO
00026 //  Module : GEOM
00027 
00028 #include "GEOM_OCCReader.h"
00029 
00030 // VTK Includes
00031 #include <vtkPoints.h>
00032 #include <vtkCellArray.h>
00033 
00034 #include <vtkObjectFactory.h>
00035 #include <vtkPolyData.h>
00036 
00037 // OpenCASCADE Includes
00038 #include <TopExp_Explorer.hxx>
00039 #include <Poly_Triangulation.hxx>
00040 #include <Poly_Polygon3D.hxx>
00041 #include <Poly_PolygonOnTriangulation.hxx>
00042 #include <TopoDS_Face.hxx>
00043 #include <TopoDS_Edge.hxx>
00044 #include <TopAbs.hxx>
00045 #include <Precision.hxx>
00046 #include <BRepTools.hxx>
00047 #include <BRep_Tool.hxx>
00048 #include <Geom2dAdaptor_Curve.hxx>
00049 #include <Geom2dHatch_Intersector.hxx>
00050 #include <Geom2dHatch_Hatcher.hxx>
00051 #include <Geom2d_Curve.hxx>
00052 #include <Geom2d_Line.hxx>
00053 #include <Geom2d_TrimmedCurve.hxx>
00054 #include <HatchGen_Domain.hxx>
00055 #include <TopAbs_ShapeEnum.hxx>
00056 #include <gp_Dir2d.hxx>
00057 #include <gp_Pnt2d.hxx>
00058 #include <TColStd_Array1OfInteger.hxx>
00059 #include <TColStd_Array1OfReal.hxx>
00060 #include <Adaptor3d_HCurve.hxx>
00061 
00062 #include "utilities.h"
00063 
00064 
00065 #define MAX2(X, Y)      (  Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
00066 #define MAX3(X, Y, Z)   ( MAX2 ( MAX2(X,Y) , Z) )
00067 
00068 // Constante for iso building
00069 static Standard_Real IntersectorConfusion = 1.e-10 ; // -8 ;
00070 static Standard_Real IntersectorTangency  = 1.e-10 ; // -8 ;
00071 static Standard_Real HatcherConfusion2d   = 1.e-8 ;
00072 static Standard_Real HatcherConfusion3d   = 1.e-8 ;
00073 
00074 static Standard_Integer lastVTKpoint = 0;
00075 static Standard_Integer PlotCount = 0;
00076 static Standard_Real IsoRatio = 1.001;
00077 static Standard_Integer MaxPlotCount = 5; 
00078 
00079 //=======================================================================
00080 // Function : New
00081 // Purpose  : 
00082 //=======================================================================
00083 
00084 GEOM_OCCReader* GEOM_OCCReader::New()
00085 {
00086   vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_OCCReader");
00087   if(ret) {
00088     return (GEOM_OCCReader*)ret;
00089   }
00090   return new GEOM_OCCReader;
00091 }
00092 
00093 //=======================================================================
00094 // Function : GEOM_OCCReader
00095 // Purpose  : 
00096 //=======================================================================
00097 
00098 GEOM_OCCReader::GEOM_OCCReader()
00099 {
00100   //this->myShape = NULL;
00101   this->amode = 0;
00102   this->forced = Standard_False;
00103   this->discretiso = 15;
00104   this->nbisos = 1;
00105 }
00106 //=======================================================================
00107 // Function : ~GEOM_OCCReader
00108 // Purpose  : 
00109 //=======================================================================
00110 
00111 GEOM_OCCReader::~GEOM_OCCReader()
00112 {
00113 }
00114 
00115 
00116 //=======================================================================
00117 // Function : Execute
00118 // Purpose  : 
00119 //=======================================================================
00120 
00121 
00122 void GEOM_OCCReader::Execute() {
00123 
00124   vtkPolyData* output = this->GetOutput();
00125   vtkPoints* Pts = NULL;
00126   vtkCellArray* Cells = NULL;
00127   TopLoc_Location aLoc;
00128 
00129   // Allocation
00130   Pts = vtkPoints::New();
00131   Cells = vtkCellArray::New();
00132         
00133   //Compute number of triangles and points
00134   Standard_Integer nbpoly=0,nbpts=0;
00135 
00136   if(amode==1) {
00137     //for shading
00138     
00139     if(myShape.ShapeType() == TopAbs_FACE) {
00140       // whole FACE 
00141       const TopoDS_Face& aFace = TopoDS::Face(myShape);
00142       Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
00143       if(aPoly.IsNull()) {
00144         Pts->Delete();
00145         Cells->Delete();
00146         return;
00147       }
00148 
00149       nbpts = aPoly->NbNodes();
00150       nbpoly = aPoly->NbTriangles();
00151 
00152       Pts->SetNumberOfPoints(nbpts);
00153       Cells->Allocate(Cells->EstimateSize(nbpoly,3));
00154     }
00155     else { 
00156         Cells->Delete();
00157         Pts->Delete();
00158         return; 
00159     }
00160   }
00161 
00162   // Start computation
00163   if(amode == 0) {
00164     ComputeWireframe(Pts,Cells);
00165     output->SetPoints(Pts);
00166     output->SetLines(Cells);
00167     output->Squeeze();
00168   }
00169   else {
00170     if(myShape.ShapeType() == TopAbs_FACE) {
00171       ComputeShading(Pts,Cells);
00172 
00173       output->SetPoints(Pts);
00174       output->SetPolys(Cells);
00175       output->Squeeze();
00176     }
00177   }
00178   Pts->Delete();
00179   Cells->Delete();
00180   
00181 }
00182 
00183 //=======================================================================
00184 // Function : ComputeWireframe
00185 // Purpose  : Compute the shape in CAD wireframe mode
00186 //=======================================================================
00187 
00188 void GEOM_OCCReader::ComputeWireframe(vtkPoints* Pts,vtkCellArray* Cells){
00189 
00190   // Check the type of the shape:
00191   if(myShape.ShapeType() == TopAbs_FACE) {
00192     // Face
00193     TransferFaceWData(TopoDS::Face(myShape),Pts,Cells);
00194   } else if(myShape.ShapeType() == TopAbs_EDGE) {
00195     // Edge
00196     TransferEdgeWData(TopoDS::Edge(myShape),Pts,Cells);
00197   } else {
00198     if(myShape.ShapeType() == TopAbs_VERTEX) {
00199       // Vertex
00200       TransferVertexWData(TopoDS::Vertex(myShape),Pts,Cells);
00201     }
00202   }
00203 }
00204 
00205 //=======================================================================
00206 // Function : TransferFaceWData
00207 // Purpose  : Transfert wireframe data for FACE
00208 //=======================================================================
00209 
00210 void GEOM_OCCReader::TransferFaceWData(const TopoDS_Face& aFace,
00211                                          vtkPoints* Pts,
00212                                          vtkCellArray* Cells) 
00213 {
00214   TopoDS_Face aCopyFace = aFace; 
00215   aCopyFace.Orientation (TopAbs_FORWARD);
00216   createISO(aCopyFace,Precision::Infinite(),1,Pts,Cells);
00217 }
00218 
00219 //=======================================================================
00220 // Function : createISO
00221 // Purpose  : Create ISO for Face Wireframe representation 
00222 //=======================================================================
00223 
00224 void GEOM_OCCReader::createISO (const TopoDS_Face&     TopologicalFace,
00225                                   const Standard_Real    Infinite,
00226                                   const Standard_Integer NbIsos,
00227                                   vtkPoints* Pts,
00228                                   vtkCellArray* Cell)
00229 {
00230   Geom2dHatch_Hatcher aHatcher (Geom2dHatch_Intersector (IntersectorConfusion,
00231                                                          IntersectorTangency),
00232                                 HatcherConfusion2d,
00233                                 HatcherConfusion3d,
00234                                 Standard_True,
00235                                 Standard_False);
00236   
00237   Standard_Real myInfinite,myUMin,myUMax,myVMin,myVMax;
00238   //myInfinite = Precision::Infinite();
00239   myInfinite = 1e38; // VTK uses float numbers - Precision::Infinite() is double and can not be accepted.
00240 
00241   Standard_Integer myNbDom;
00242   TColStd_Array1OfReal myUPrm(1, NbIsos),myVPrm(1, NbIsos);
00243   TColStd_Array1OfInteger myUInd(1, NbIsos),myVInd(1, NbIsos);
00244 
00245   myUInd.Init(0);
00246   myVInd.Init(0);
00247 
00248   //-----------------------------------------------------------------------
00249   // If the Min Max bounds are infinite, there are bounded to Infinite
00250   // value.
00251   //-----------------------------------------------------------------------
00252 
00253   BRepTools::UVBounds (TopologicalFace, myUMin, myUMax, myVMin, myVMax) ;
00254   Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (myUMin) ;
00255   Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (myUMax) ;
00256   Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (myVMin) ;
00257   Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (myVMax) ;
00258   if (InfiniteUMin && InfiniteUMax) {
00259     myUMin = - myInfinite ;
00260     myUMax =   myInfinite ;
00261   } else if (InfiniteUMin) {
00262     myUMin = myUMax - myInfinite ;
00263   } else if (InfiniteUMax) {
00264     myUMax = myUMin + myInfinite ;
00265   }
00266   if (InfiniteVMin && InfiniteVMax) {
00267     myVMin = - myInfinite ;
00268     myVMax =   myInfinite ;
00269   } else if (InfiniteVMin) {
00270     myVMin = myVMax - myInfinite ;
00271   } else if (InfiniteVMax) {
00272     myVMax = myVMin + myInfinite ;
00273   }
00274 
00275   //-----------------------------------------------------------------------
00276   // Retreiving the edges and loading them into the hatcher.
00277   //-----------------------------------------------------------------------
00278 
00279   TopExp_Explorer ExpEdges ;
00280   for (ExpEdges.Init (TopologicalFace, TopAbs_EDGE) ; ExpEdges.More() ; ExpEdges.Next()) {
00281     const TopoDS_Edge& TopologicalEdge = TopoDS::Edge (ExpEdges.Current()) ;
00282     Standard_Real U1, U2 ;
00283     const Handle(Geom2d_Curve) PCurve = BRep_Tool::CurveOnSurface (TopologicalEdge, TopologicalFace, U1, U2) ;
00284 
00285     if ( PCurve.IsNull() ) {
00286       return;
00287     }
00288 
00289     if ( U1==U2) {
00290       return;
00291     }
00292 
00293     //-- Test if a TrimmedCurve is necessary
00294     if(   Abs(PCurve->FirstParameter()-U1)<= Precision::PConfusion() 
00295           && Abs(PCurve->LastParameter()-U2)<= Precision::PConfusion()) { 
00296       aHatcher.AddElement (PCurve, TopologicalEdge.Orientation()) ;      
00297     }
00298     else { 
00299       if (!PCurve->IsPeriodic()) {
00300         Handle (Geom2d_TrimmedCurve) TrimPCurve =Handle(Geom2d_TrimmedCurve)::DownCast(PCurve);
00301         if (!TrimPCurve.IsNull()) {
00302           if (TrimPCurve->BasisCurve()->FirstParameter()-U1 > Precision::PConfusion() ||
00303               U2-TrimPCurve->BasisCurve()->LastParameter()  > Precision::PConfusion()) {
00304             aHatcher.AddElement (PCurve, TopologicalEdge.Orientation()) ;      
00305             return;
00306           }
00307         }
00308         else {
00309           if (PCurve->FirstParameter()-U1 > Precision::PConfusion()){
00310             U1=PCurve->FirstParameter();
00311           }
00312           if (U2-PCurve->LastParameter()  > Precision::PConfusion()){
00313             U2=PCurve->LastParameter();
00314           }
00315         }
00316       }
00317       Handle (Geom2d_TrimmedCurve) TrimPCurve = new Geom2d_TrimmedCurve (PCurve, U1, U2) ;
00318       aHatcher.AddElement (TrimPCurve, TopologicalEdge.Orientation()) ;
00319     }
00320   }
00321 
00322 
00323   //-----------------------------------------------------------------------
00324   // Loading and trimming the hatchings.
00325   //-----------------------------------------------------------------------
00326 
00327   Standard_Integer IIso ;
00328   Standard_Real DeltaU = Abs (myUMax - myUMin) ;
00329   Standard_Real DeltaV = Abs (myVMax - myVMin) ;
00330   Standard_Real confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d ;
00331   aHatcher.Confusion3d (confusion) ;
00332 
00333   Standard_Real StepU = DeltaU / (Standard_Real) NbIsos ;
00334   if (StepU > confusion) {
00335     Standard_Real UPrm = myUMin + StepU / 2. ;
00336     gp_Dir2d Dir (0., 1.) ;
00337     for (IIso = 1 ; IIso <= NbIsos ; IIso++) {
00338       myUPrm(IIso) = UPrm ;
00339       gp_Pnt2d Ori (UPrm, 0.) ;
00340       Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ;
00341       myUInd(IIso) = aHatcher.AddHatching (HCur) ;
00342       UPrm += StepU ;
00343     }
00344   }
00345 
00346   Standard_Real StepV = DeltaV / (Standard_Real) NbIsos ;
00347   if (StepV > confusion) {
00348     Standard_Real VPrm = myVMin + StepV / 2. ;
00349     gp_Dir2d Dir (1., 0.) ;
00350     for (IIso = 1 ; IIso <= NbIsos ; IIso++) {
00351       myVPrm(IIso) = VPrm ;
00352       gp_Pnt2d Ori (0., VPrm) ;
00353       Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ;
00354       myVInd(IIso) = aHatcher.AddHatching (HCur) ;
00355       VPrm += StepV ;
00356     }
00357   }
00358 
00359   //-----------------------------------------------------------------------
00360   // Computation.
00361   //-----------------------------------------------------------------------
00362 
00363   aHatcher.Trim() ;
00364 
00365   myNbDom = 0 ;
00366   for (IIso = 1 ; IIso <= NbIsos ; IIso++) {
00367     Standard_Integer Index ;
00368 
00369     Index = myUInd(IIso) ;
00370     if (Index != 0) {
00371       if (aHatcher.TrimDone (Index) && !aHatcher.TrimFailed (Index)) {
00372         aHatcher.ComputeDomains (Index);
00373         if (aHatcher.IsDone (Index)) myNbDom = myNbDom + aHatcher.NbDomains (Index) ;
00374       }
00375     }
00376 
00377     Index = myVInd(IIso) ;
00378     if (Index != 0) {
00379       if (aHatcher.TrimDone (Index) && !aHatcher.TrimFailed (Index)) {
00380         aHatcher.ComputeDomains (Index);
00381         if (aHatcher.IsDone (Index)) myNbDom = myNbDom + aHatcher.NbDomains (Index) ;
00382       }
00383     }
00384   }
00385 
00386   //-----------------------------------------------------------------------
00387   // Push iso lines in vtk kernel
00388   //-----------------------------------------------------------------------
00389 
00390 
00391   Standard_Integer pt_start_idx = 0;
00392 
00393   for (Standard_Integer UIso = myUPrm.Lower() ; UIso <= myUPrm.Upper() ; UIso++) {
00394     Standard_Integer UInd = myUInd.Value (UIso) ;
00395     if (UInd != 0) {
00396       Standard_Real UPrm = myUPrm.Value (UIso) ;
00397       if (!aHatcher.IsDone (UInd)) {
00398         MESSAGE("DBRep_IsoBuilder:: U iso of parameter: "<<UPrm)
00399         switch (aHatcher.Status (UInd)) {
00400         case HatchGen_NoProblem          : MESSAGE("No Problem")          ; break ;
00401         case HatchGen_TrimFailure        : MESSAGE("Trim Failure")        ; break ;
00402         case HatchGen_TransitionFailure  : MESSAGE("Transition Failure")  ; break ;
00403         case HatchGen_IncoherentParity   : MESSAGE("Incoherent Parity")   ; break ;
00404         case HatchGen_IncompatibleStates : MESSAGE("Incompatible States") ; break ;
00405         }
00406       } else {
00407         Standard_Integer NbDom = aHatcher.NbDomains (UInd) ;
00408         for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++) {
00409           const HatchGen_Domain& Dom = aHatcher.Domain (UInd, IDom) ;
00410           Standard_Real V1 = Dom.HasFirstPoint()  ? Dom.FirstPoint().Parameter()  : myVMin - myInfinite ;
00411           Standard_Real V2 = Dom.HasSecondPoint() ? Dom.SecondPoint().Parameter() : myVMax + myInfinite ;
00412           DrawIso(GeomAbs_IsoU, UPrm, V1, V2, Pts, Cell,pt_start_idx);
00413         }
00414       }
00415     }
00416   }
00417 
00418   for (Standard_Integer VIso = myVPrm.Lower() ; VIso <= myVPrm.Upper() ; VIso++) {
00419     Standard_Integer VInd = myVInd.Value (VIso) ;
00420     if (VInd != 0) {
00421       Standard_Real VPrm = myVPrm.Value (VIso) ;
00422       if (!aHatcher.IsDone (VInd)) {
00423         MESSAGE("DBRep_IsoBuilder:: V iso of parameter: "<<VPrm)
00424         switch (aHatcher.Status (VInd)) {
00425         case HatchGen_NoProblem          : MESSAGE("No Problem")          ; break ;
00426         case HatchGen_TrimFailure        : MESSAGE("Trim Failure")        ; break ;
00427         case HatchGen_TransitionFailure  : MESSAGE("Transition Failure")  ; break ;
00428         case HatchGen_IncoherentParity   : MESSAGE("Incoherent Parity")   ; break ;
00429         case HatchGen_IncompatibleStates : MESSAGE("Incompatible States") ; break ;
00430         }
00431       } else {
00432         Standard_Integer NbDom = aHatcher.NbDomains (VInd) ;
00433         for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++) {
00434           const HatchGen_Domain& Dom = aHatcher.Domain (VInd, IDom) ;
00435           Standard_Real U1 = Dom.HasFirstPoint()  ? Dom.FirstPoint().Parameter()  : myVMin - myInfinite ;
00436           Standard_Real U2 = Dom.HasSecondPoint() ? Dom.SecondPoint().Parameter() : myVMax + myInfinite ;
00437           DrawIso(GeomAbs_IsoV, VPrm, U1, U2, Pts, Cell,pt_start_idx) ;
00438         }
00439       }
00440     }
00441   }
00442 
00443 }
00444 
00445 //=======================================================================
00446 // Function : MoveTo
00447 // Purpose  : Init VTK ISO PLOT
00448 //=======================================================================
00449 void GEOM_OCCReader::MoveTo(gp_Pnt P,
00450                               vtkPoints* Pts)
00451 {    
00452   float coord[3];
00453 
00454   coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
00455   lastVTKpoint = Pts->InsertNextPoint(coord);
00456     
00457 } 
00458 
00459 //=======================================================================
00460 // Function : DrawTo
00461 // Purpose  : Plot point in VTK
00462 //=======================================================================
00463 void GEOM_OCCReader::DrawTo(gp_Pnt P,
00464                               vtkPoints* Pts,
00465                               vtkCellArray* Cells)
00466 {
00467   float coord[3];
00468   coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
00469   Standard_Integer NewVTKpoint =  Pts->InsertNextPoint(coord);
00470 
00471   vtkIdType pts[2];
00472   pts[0] = lastVTKpoint;
00473   pts[1] = NewVTKpoint;
00474 
00475   Cells->InsertNextCell(2,pts);
00476     
00477   lastVTKpoint = NewVTKpoint;
00478 }
00479 
00480 
00481 //=======================================================================
00482 // Function : DrawIso
00483 // Purpose  : Draw an iso on vtk
00484 //=======================================================================
00485 void GEOM_OCCReader::DrawIso(GeomAbs_IsoType T, 
00486                                Standard_Real Par, 
00487                                Standard_Real T1,
00488                                Standard_Real T2,
00489                                vtkPoints* Pts,
00490                                vtkCellArray* Cells,
00491                                Standard_Integer& startidx)
00492 {
00493 
00494   Standard_Boolean halt = Standard_False;
00495   Standard_Integer j,myDiscret = discretiso;
00496   Standard_Real U1,U2,V1,V2,stepU=0.,stepV=0.;
00497   gp_Pnt P;
00498   TopLoc_Location l;
00499 
00500   const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(myShape),l);
00501   if (!S.IsNull()) {
00502     BRepAdaptor_Surface S(TopoDS::Face(myShape),Standard_False);
00503       
00504     GeomAbs_SurfaceType SurfType = S.GetType();
00505 
00506     GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
00507 
00508     Standard_Integer Intrv, nbIntv;
00509     Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
00510     Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
00511     TColStd_Array1OfReal TI(1,Max(nbUIntv, nbVIntv)+1);
00512 
00513 
00514     if (T == GeomAbs_IsoU) {
00515       S.VIntervals(TI, GeomAbs_CN);
00516       V1 = Max(T1, TI(1));
00517       V2 = Min(T2, TI(2));
00518       U1 = Par;
00519       U2 = Par;
00520       stepU = 0;
00521       nbIntv = nbVIntv;
00522     }
00523     else {
00524       S.UIntervals(TI, GeomAbs_CN);
00525       U1 = Max(T1, TI(1));
00526       U2 = Min(T2, TI(2));
00527       V1 = Par;
00528       V2 = Par;
00529       stepV = 0;
00530       nbIntv = nbUIntv;
00531     }   
00532         
00533     S.D0(U1,V1,P);
00534     MoveTo(P,Pts);
00535 
00536     for (Intrv = 1; Intrv <= nbIntv; Intrv++) {
00537 
00538       if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
00539         continue;
00540       if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
00541         continue;
00542       if (T == GeomAbs_IsoU) {
00543         V1 = Max(T1, TI(Intrv));
00544         V2 = Min(T2, TI(Intrv + 1));
00545         stepV = (V2 - V1) / myDiscret;
00546       }
00547       else {
00548         U1 = Max(T1, TI(Intrv));
00549         U2 = Min(T2, TI(Intrv + 1));
00550         stepU = (U2 - U1) / myDiscret;
00551       }
00552 
00553       switch (SurfType) {
00554         //-------------GeomAbs_Plane---------------
00555       case GeomAbs_Plane :
00556         break;
00557         //----GeomAbs_Cylinder   GeomAbs_Cone------
00558       case GeomAbs_Cylinder :
00559       case GeomAbs_Cone :
00560         if (T == GeomAbs_IsoV) {
00561           for (j = 1; j < myDiscret; j++) {
00562             U1 += stepU;
00563             V1 += stepV;
00564             S.D0(U1,V1,P);
00565             DrawTo(P,Pts,Cells);
00566           }
00567         }
00568         break;
00569         //---GeomAbs_Sphere   GeomAbs_Torus--------
00570         //GeomAbs_BezierSurface GeomAbs_BezierSurface
00571       case GeomAbs_Sphere :
00572       case GeomAbs_Torus :
00573       case GeomAbs_OffsetSurface :
00574       case GeomAbs_OtherSurface :
00575         for (j = 1; j < myDiscret; j++) {
00576           U1 += stepU;
00577           V1 += stepV;
00578           S.D0(U1,V1,P);
00579           DrawTo(P,Pts,Cells);
00580         }
00581         break;
00582         //-------------GeomAbs_BSplineSurface------
00583       case GeomAbs_BezierSurface :
00584       case GeomAbs_BSplineSurface :
00585         for (j = 1; j <= myDiscret/2; j++) {
00586 
00587           PlotCount = 0;
00588 
00589           PlotIso ( S, T, U1, V1, (T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells);
00590           U1 += stepU*2.;
00591           V1 += stepV*2.;
00592         }
00593         break;
00594         //-------------GeomAbs_SurfaceOfExtrusion--
00595         //-------------GeomAbs_SurfaceOfRevolution-
00596       case GeomAbs_SurfaceOfExtrusion :
00597       case GeomAbs_SurfaceOfRevolution :
00598         if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution) ||
00599             (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion)) {
00600           if (SurfType == GeomAbs_SurfaceOfExtrusion) break;
00601           for (j = 1; j < myDiscret; j++) {
00602             U1 += stepU;
00603             V1 += stepV;
00604             S.D0(U1,V1,P);
00605             DrawTo(P,Pts,Cells);
00606           }
00607         } else {
00608           CurvType = (S.BasisCurve())->GetType();
00609           switch (CurvType) {
00610           case GeomAbs_Line :
00611             break;
00612           case GeomAbs_Circle :
00613           case GeomAbs_Ellipse :
00614             for (j = 1; j < myDiscret; j++) {
00615               U1 += stepU;
00616               V1 += stepV;
00617               S.D0(U1,V1,P);
00618               DrawTo(P,Pts,Cells);
00619             }
00620             break;
00621           case GeomAbs_Parabola :
00622           case GeomAbs_Hyperbola :
00623           case GeomAbs_BezierCurve :
00624           case GeomAbs_BSplineCurve :
00625           case GeomAbs_OtherCurve :
00626             for (j = 1; j <= myDiscret/2; j++) {
00627 
00628               PlotCount = 0;
00629 
00630               PlotIso ( S, T, U1, V1,(T == GeomAbs_IsoV) ? stepU*2. : stepV*2., halt, Pts, Cells);
00631               U1 += stepU*2.;
00632               V1 += stepV*2.;
00633             }
00634             break;
00635           }
00636         }
00637       }
00638     }
00639     S.D0(U2,V2,P);
00640     DrawTo(P,Pts,Cells);
00641   }  
00642 }
00643 
00644 //=======================================================================
00645 // Function : PlotIso
00646 // Purpose  : Plot iso for other surface
00647 //=======================================================================
00648 
00649 void GEOM_OCCReader::PlotIso (BRepAdaptor_Surface& S, 
00650                                 GeomAbs_IsoType T,
00651                                 Standard_Real& U, 
00652                                 Standard_Real& V, 
00653                                 Standard_Real Step, 
00654                                 Standard_Boolean& halt,
00655                                 vtkPoints* Pts,
00656                                 vtkCellArray* Cells)
00657 {
00658 
00659   ++PlotCount; 
00660 
00661   gp_Pnt Pl, Pr, Pm;
00662 
00663   if (T == GeomAbs_IsoU) {
00664     S.D0(U, V, Pl);
00665     S.D0(U, V + Step/2., Pm);
00666     S.D0(U, V + Step, Pr);
00667   } else {
00668     S.D0(U, V, Pl);
00669     S.D0(U + Step/2., V, Pm);
00670     S.D0(U + Step, V, Pr);
00671   }
00672 
00673   if (PlotCount > MaxPlotCount) {
00674     DrawTo(Pr,Pts,Cells);
00675     return;
00676   }
00677 
00678   if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio*Pl.Distance(Pr)) {
00679     DrawTo(Pr,Pts,Cells);
00680   } else 
00681     if (T == GeomAbs_IsoU) {
00682       PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells);
00683       Standard_Real aLocalV = V + Step/2 ;
00684       PlotIso ( S, T, U, aLocalV , Step/2, halt, Pts, Cells);
00685     } else {
00686       PlotIso ( S, T, U, V, Step/2, halt, Pts, Cells);
00687       Standard_Real aLocalU = U + Step/2 ;
00688       PlotIso ( S, T, aLocalU , V, Step/2, halt, Pts, Cells);
00689     }
00690 }
00691 
00692 //=======================================================================
00693 // Function : TransferEdgeWData
00694 // Purpose  : Transfert wireframe data for EDGE
00695 //=======================================================================
00696 
00697 void GEOM_OCCReader::TransferEdgeWData(const TopoDS_Edge& aEdge,
00698                                          vtkPoints* Pts,
00699                                          vtkCellArray* Cells) {
00700   
00701   
00702   Handle(Poly_PolygonOnTriangulation) aEdgePoly;
00703   Standard_Integer i = 1;
00704   Handle(Poly_Triangulation) T;
00705   TopLoc_Location aEdgeLoc;
00706   BRep_Tool::PolygonOnTriangulation(aEdge, aEdgePoly, T, aEdgeLoc, i);
00707   
00708   Handle(Poly_Polygon3D) P;
00709   if(aEdgePoly.IsNull()) {
00710     P = BRep_Tool::Polygon3D(aEdge, aEdgeLoc);
00711   }
00712 
00713   if(P.IsNull() && aEdgePoly.IsNull())
00714     return;
00715   
00716   // Location edges
00717   //---------------
00718   
00719   gp_Trsf edgeTransf;
00720   Standard_Boolean isidtrsf = true;
00721   if(!aEdgeLoc.IsIdentity())  {
00722     isidtrsf = false;
00723     edgeTransf = aEdgeLoc.Transformation();
00724   }
00725 
00726   gp_Pnt aP1, aP2;
00727 
00728   Standard_Integer nbnodes;
00729   if (aEdgePoly.IsNull()) {
00730     nbnodes = P->NbNodes();
00731     const TColgp_Array1OfPnt& theNodesP = P->Nodes();
00732 
00733     aP1 = theNodesP(1);
00734     aP2 = theNodesP(nbnodes);
00735 
00736     float coord[3];
00737     vtkIdType pts[2];
00738 
00739     for(int j=1;j<nbnodes;j++) {
00740       gp_Pnt pt1 = theNodesP(j);
00741       gp_Pnt pt2 = theNodesP(j+1);
00742     
00743       if(!isidtrsf) {
00744         // apply edge transformation
00745         pt1.Transform(edgeTransf);
00746         pt2.Transform(edgeTransf);
00747       }
00748       
00749       // insert pt1
00750       coord[0] = pt1.X(); coord[1] = pt1.Y(); coord[2] = pt1.Z();
00751       pts[0] = Pts->InsertNextPoint(coord);
00752       
00753       // insert pt2
00754       coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z();
00755       pts[1] = Pts->InsertNextPoint(coord);
00756       
00757       // insert line (pt1,pt2)
00758       Cells->InsertNextCell(2,pts);
00759     }
00760   } else {
00761     nbnodes = aEdgePoly->NbNodes();
00762     const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes();
00763     const TColgp_Array1OfPnt& theNodesPoly = T->Nodes();
00764 
00765     aP1 = theNodesPoly(1);
00766     aP2 = theNodesPoly(nbnodes);
00767 
00768     float coord[3];
00769     vtkIdType pts[2];
00770     
00771     for(int j=1;j<nbnodes;j++) {
00772       Standard_Integer id1 = Nodesidx(j);
00773       Standard_Integer id2 = Nodesidx(j+1);
00774       
00775       gp_Pnt pt1 = theNodesPoly(id1);
00776       gp_Pnt pt2 = theNodesPoly(id2);
00777           
00778       if(!isidtrsf) {
00779         // apply edge transformation
00780         pt1.Transform(edgeTransf);
00781         pt2.Transform(edgeTransf);
00782       }
00783       
00784       // insert pt1
00785       coord[0] = pt1.X(); coord[1] = pt1.Y(); coord[2] = pt1.Z();
00786       pts[0] = Pts->InsertNextPoint(coord);
00787       
00788       // insert pt2
00789       coord[0] = pt2.X(); coord[1] = pt2.Y(); coord[2] = pt2.Z();
00790       pts[1] = Pts->InsertNextPoint(coord);
00791       
00792       // insert line (pt1,pt2)
00793       Cells->InsertNextCell(2,pts);
00794     }
00795   }
00796 
00797   // vector representation has an arrow on its end
00798   if (myIsVector)
00799   {
00800     if (!isidtrsf) {
00801       // apply edge transformation
00802       aP1.Transform(edgeTransf);
00803       aP2.Transform(edgeTransf);
00804     }
00805 
00806     // draw an arrow
00807     gp_Vec aDirVec (aP1, aP2);
00808     Standard_Real aDist = aDirVec.Magnitude();
00809     if (aDist < gp::Resolution()) return;
00810     gp_Dir aDirection (aDirVec);
00811 
00812     Standard_Real anAngle = M_PI/180. * 5.;
00813     Standard_Real aLength = aDist/10.;
00814 
00815     Standard_Real dx,dy,dz;
00816     aDirection.Coord(dx,dy,dz);
00817 
00818     // Pointe de la fleche
00819     Standard_Real xo,yo,zo;
00820     aP2.Coord(xo,yo,zo);
00821 
00822     // Centre du cercle base de la fleche
00823     gp_XYZ aPc = aP2.XYZ() - aDirection.XYZ() * aLength;
00824 
00825     // Construction d'un repere i,j pour le cercle
00826     gp_Dir aDirN;
00827     if      (Abs(dx) <= Abs(dy) && Abs(dx) <= Abs(dz)) aDirN = gp::DX();
00828     else if (Abs(dy) <= Abs(dz) && Abs(dy) <= Abs(dx)) aDirN = gp::DY();
00829     else aDirN = gp::DZ();
00830 
00831     gp_Dir aDirI = aDirection ^ aDirN;
00832     gp_Dir aDirJ = aDirection ^ aDirI;
00833 
00834     // Add points and segments, composing the arrow
00835     Standard_Real cosinus, sinus, Tg = tan(anAngle);
00836 
00837     float coord[3];
00838     coord[0] = xo; coord[1] = yo; coord[2] = zo;
00839 
00840     int ptLoc = Pts->InsertNextPoint(coord);
00841     int ptFirst = 0;
00842     int ptPrev = 0;
00843     int ptCur = 0;
00844 
00845     vtkIdType pts[2];
00846 
00847     int NbPoints = 15;
00848     for (int i = 1; i <= NbPoints; i++, ptPrev = ptCur)
00849     {
00850       cosinus = cos(2. * M_PI / NbPoints * (i-1));   
00851       sinus   = sin(2. * M_PI / NbPoints * (i-1));
00852 
00853       gp_XYZ aP = aPc + (aDirI.XYZ() * cosinus + aDirJ.XYZ() * sinus) * aLength * Tg;
00854       coord[0] = aP.X();
00855       coord[1] = aP.Y();
00856       coord[2] = aP.Z();
00857 
00858       // insert pts
00859       ptCur = Pts->InsertNextPoint(coord);
00860       pts[0] = ptCur;
00861 
00862       if (i == 1) {
00863         ptFirst = ptCur;
00864       }
00865       else {
00866         // insert line (ptCur,ptPrev)
00867         pts[1] = ptPrev;
00868         Cells->InsertNextCell(2,pts);
00869       }
00870 
00871       // insert line (ptCur,ptLoc)
00872       pts[1] = ptLoc;
00873       Cells->InsertNextCell(2,pts);
00874     }
00875 
00876     // insert line (ptCur,ptFirst)
00877     pts[0] = ptCur;
00878     pts[1] = ptFirst;
00879     Cells->InsertNextCell(2,pts);
00880   }
00881 }
00882 
00883 /*  Standard_Integer nbnodes = aEdgePoly->NbNodes();
00884   const TColStd_Array1OfInteger& Nodesidx = aEdgePoly->Nodes();
00885   const TColgp_Array1OfPnt& theNodes = T->Nodes();
00886     
00887   float coord[3];
00888   vtkIdType pts[2];
00889     
00890 
00891   // PUSH NODES
00892   for(i=1;i<=nbnodes;i++) {
00893     Standard_Integer id = Nodesidx(i);
00894     gp_Pnt pt = theNodes(id);
00895  
00896     float coord[3];
00897     if(!isidtrsf) pt.Transform(edgeTransf);
00898 
00899     coord[0] = pt.X(); coord[1] = pt.Y(); coord[2] = pt.Z();
00900 
00901     Pts->SetPoint(id-1,coord);
00902 
00903   }
00904 
00905   // PUSH EDGES
00906   for(i=1;i<nbnodes;i++) {
00907       
00908     Standard_Integer id1 = Nodesidx(i);
00909     Standard_Integer id2 = Nodesidx(i+1);
00910     
00911     vtkIdType pts[2];
00912     pts[0] = id1-1; pts[1] = id2-1;
00913 
00914     // insert line (pt1,pt2)
00915     Cells->InsertNextCell(2,pts);
00916   }
00917  
00918   
00919   }*/
00920 
00921 //=======================================================================
00922 // Function : TransferVertexWData
00923 // Purpose  : Transfert wireframe data for VERTEX
00924 //=======================================================================
00925 
00926 void GEOM_OCCReader::TransferVertexWData(const TopoDS_Vertex& aVertex,
00927                                          vtkPoints* Pts,
00928                                          vtkCellArray* Cells) {
00929 #define ZERO_COORD coord[0] = 0.0; coord[1] = 0.0; coord[2] = 0.0
00930   
00931   gp_Pnt P = BRep_Tool::Pnt( aVertex );
00932   float delta = 1, coord[3];
00933   vtkIdType pts[2];
00934   // insert pt
00935   ZERO_COORD; coord[0] = +delta;
00936   pts[0] = Pts->InsertNextPoint(coord);
00937   coord[0] = -delta;
00938   pts[1] = Pts->InsertNextPoint(coord);
00939   // insert line (pt1,pt2)
00940   Cells->InsertNextCell(2,pts);
00941 
00942   ZERO_COORD; coord[1] = +delta;
00943   pts[0] = Pts->InsertNextPoint(coord);
00944   coord[1] = -delta;
00945   pts[1] = Pts->InsertNextPoint(coord);
00946   // insert line (pt1,pt2)
00947   Cells->InsertNextCell(2,pts);
00948 
00949   ZERO_COORD; coord[2] = +delta;
00950   pts[0] = Pts->InsertNextPoint(coord);
00951   coord[2] = -delta;
00952   pts[1] = Pts->InsertNextPoint(coord);
00953   // insert line (pt1,pt2)
00954   Cells->InsertNextCell(2,pts);
00955 
00956 #undef ZERO_COORD
00957 }       
00958 
00959 //=======================================================================
00960 // Function : TransferEdgeSData(
00961 // Purpose  : Transfert shading data for EDGE
00962 //=======================================================================
00963 
00964 void GEOM_OCCReader::TransferEdgeSData(const TopoDS_Edge& aFace,
00965                                          vtkPoints* Pts,
00966                                          vtkCellArray* Cells) 
00967 {
00968 }
00969 
00970 
00971 //=======================================================================
00972 // Function : TransferFaceSData
00973 // Purpose  : Transfert shading data for FACE
00974 //=======================================================================
00975 void GEOM_OCCReader::TransferFaceSData(const TopoDS_Face& aFace,
00976                                          vtkPoints* Pts,
00977                                          vtkCellArray* Cells) {
00978 
00979   TopLoc_Location aLoc;
00980   Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
00981   if(aPoly.IsNull()) return;
00982   else {
00983     
00984     gp_Trsf myTransf;
00985     Standard_Boolean identity = true;
00986     if(!aLoc.IsIdentity())  {
00987       identity = false;
00988       myTransf = aLoc.Transformation();
00989     }
00990 
00991     Standard_Integer nbNodesInFace = aPoly->NbNodes();
00992     Standard_Integer nbTriInFace = aPoly->NbTriangles();
00993                 
00994     const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
00995     const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
00996       
00997     Standard_Integer i;
00998     for(i=1;i<=nbNodesInFace;i++) {
00999       gp_Pnt P = Nodes(i);
01000       float coord[3];
01001       if(!identity) P.Transform(myTransf);
01002       coord[0] = P.X(); coord[1] = P.Y(); coord[2] = P.Z();
01003       Pts->SetPoint(i-1,coord);
01004     }
01005 
01006     for(i=1;i<=nbTriInFace;i++) {
01007       // Get the triangle
01008         
01009       Standard_Integer N1,N2,N3;
01010       Triangles(i).Get(N1,N2,N3);
01011         
01012       vtkIdType pts[3];
01013       pts[0] = N1-1; pts[1] = N2-1; pts[2] = N3-1;
01014       Cells->InsertNextCell(3,pts);
01015 
01016     }
01017   } 
01018 }
01019 
01020 //=======================================================================
01021 // Function : ComputeShading
01022 // Purpose  : Compute the shape in shading mode
01023 //=======================================================================
01024 void GEOM_OCCReader::ComputeShading(vtkPoints* Pts,vtkCellArray* Cells){
01025 
01026   // Check the type of the shape:
01027   if(myShape.ShapeType() == TopAbs_FACE) {
01028     // Face
01029     TransferFaceSData(TopoDS::Face(myShape),Pts,Cells);
01030   }
01031   else {
01032     if(myShape.ShapeType() == TopAbs_EDGE) {
01033       // Edge
01034       TransferEdgeSData(TopoDS::Edge(myShape),Pts,Cells);
01035     }
01036     else {
01037     }
01038 
01039   } 
01040 
01041 }
01042 
01043 //=======================================================================
01044 // Function : 
01045 // Purpose  : Set parameters
01046 //=======================================================================
01047 void GEOM_OCCReader::setDisplayMode(int thenewmode) {
01048   amode = thenewmode;
01049 }
01050 
01051 void GEOM_OCCReader::setTopo(const TopoDS_Shape& aShape, bool isVector) {
01052   myShape = aShape;
01053   myIsVector = isVector;
01054 }
01055 
01056 void GEOM_OCCReader::setForceUpdate(Standard_Boolean bol) {
01057   forced = bol;
01058 }
01059 
01060 //=======================================================================
01061 // Function : 
01062 // Purpose  : Get parameters
01063 //=======================================================================
01064 const TopoDS_Shape& GEOM_OCCReader::getTopo() {
01065   return myShape;
01066 }
01067 
01068 int GEOM_OCCReader::getDisplayMode() {
01069   return amode;
01070 }